@@ -2,100 +2,130 @@ package com.github.mauricio.async.db.postgresql
2
2
3
3
import org .specs2 .mutable .Specification
4
4
import com .github .mauricio .async .db .util .Log
5
- import com .github .mauricio .async .db .exceptions .DatabaseException
6
5
import scala .concurrent .ExecutionContext .Implicits .global
7
- import scala . util . control . Exception . catching
6
+ import com . github . mauricio . async . db . postgresql . exceptions . GenericDatabaseException
8
7
9
8
class TransactionSpec extends Specification with DatabaseTestHelper {
10
9
11
10
val log = Log .get[TransactionSpec ]
12
11
13
12
val tableCreate = " CREATE TEMP TABLE transaction_test (x integer PRIMARY KEY)"
14
- def tableInsert (x : Int ) = " INSERT INTO transaction_test VALUES (" + x.toString + " )"
13
+
14
+ def tableInsert (x : Int ) = " INSERT INTO transaction_test VALUES (" + x.toString + " )"
15
+
15
16
val tableSelect = " SELECT x FROM transaction_test ORDER BY x"
16
17
17
18
" transactions" should {
18
19
19
20
" commit simple inserts" in {
20
- withHandler { handler =>
21
- executeDdl(handler, tableCreate)
22
- await(handler.inTransaction { conn =>
23
- conn.sendQuery(tableInsert(1 )).flatMap { _ =>
24
- conn.sendQuery(tableInsert(2 ))
25
- }
26
- })
21
+ withHandler {
22
+ handler =>
23
+ executeDdl(handler, tableCreate)
24
+ await(handler.inTransaction {
25
+ conn =>
26
+ conn.sendQuery(tableInsert(1 )).flatMap {
27
+ _ =>
28
+ conn.sendQuery(tableInsert(2 ))
29
+ }
30
+ })
27
31
28
- val rows = executeQuery(handler, tableSelect).rows.get
29
- rows.length === 2
30
- rows(0 )(0 ) === 1
31
- rows(1 )(0 ) === 2
32
+ val rows = executeQuery(handler, tableSelect).rows.get
33
+ rows.length === 2
34
+ rows(0 )(0 ) === 1
35
+ rows(1 )(0 ) === 2
32
36
}
33
37
}
34
38
35
39
" commit simple inserts with prepared statements" in {
36
- withHandler { handler =>
37
- executeDdl(handler, tableCreate)
38
- await(handler.inTransaction { conn =>
39
- conn.sendPreparedStatement(tableInsert(1 )).flatMap { _ =>
40
- conn.sendPreparedStatement(tableInsert(2 ))
41
- }
42
- })
40
+ withHandler {
41
+ handler =>
42
+ executeDdl(handler, tableCreate)
43
+ await(handler.inTransaction {
44
+ conn =>
45
+ conn.sendPreparedStatement(tableInsert(1 )).flatMap {
46
+ _ =>
47
+ conn.sendPreparedStatement(tableInsert(2 ))
48
+ }
49
+ })
43
50
44
- val rows = executePreparedStatement(handler, tableSelect).rows.get
45
- rows.length === 2
46
- rows(0 )(0 ) === 1
47
- rows(1 )(0 ) === 2
51
+ val rows = executePreparedStatement(handler, tableSelect).rows.get
52
+ rows.length === 2
53
+ rows(0 )(0 ) === 1
54
+ rows(1 )(0 ) === 2
48
55
}
49
56
}
50
57
51
58
" rollback on error" in {
52
- withHandler { handler =>
53
- executeDdl(handler, tableCreate)
54
- catching(classOf [DatabaseException ]).opt(
55
- await(handler.inTransaction { conn =>
56
- conn.sendQuery(tableInsert(1 )).flatMap { _ =>
57
- conn.sendQuery(tableInsert(1 ))
59
+ withHandler {
60
+ handler =>
61
+ executeDdl(handler, tableCreate)
62
+
63
+ try {
64
+ await(handler.inTransaction {
65
+ conn =>
66
+ conn.sendQuery(tableInsert(1 )).flatMap {
67
+ _ =>
68
+ conn.sendQuery(tableInsert(1 ))
69
+ }
70
+ })
71
+ failure(" Should not have come here" )
72
+ } catch {
73
+ case e : GenericDatabaseException => {
74
+ e.errorMessage.message === " duplicate key value violates unique constraint \" transaction_test_pkey\" "
58
75
}
59
- })
60
- ) === None
76
+ }
61
77
62
- val rows = executeQuery(handler, tableSelect).rows.get
63
- rows.length === 0
78
+ val rows = executeQuery(handler, tableSelect).rows.get
79
+ rows.length === 0
64
80
}
65
81
82
+ }
83
+
84
+ " do not reuse connection in pool if the transaction failed" in {
85
+
86
+
87
+
66
88
}
67
89
68
90
" rollback explicitly" in {
69
- withHandler { handler =>
70
- executeDdl(handler, tableCreate)
71
- await(handler.inTransaction { conn =>
72
- conn.sendQuery(tableInsert(1 )).flatMap { _ =>
73
- conn.sendQuery(" ROLLBACK" )
74
- }
75
- })
91
+ withHandler {
92
+ handler =>
93
+ executeDdl(handler, tableCreate)
94
+ await(handler.inTransaction {
95
+ conn =>
96
+ conn.sendQuery(tableInsert(1 )).flatMap {
97
+ _ =>
98
+ conn.sendQuery(" ROLLBACK" )
99
+ }
100
+ })
76
101
77
- val rows = executeQuery(handler, tableSelect).rows.get
78
- rows.length === 0
102
+ val rows = executeQuery(handler, tableSelect).rows.get
103
+ rows.length === 0
79
104
}
80
105
81
106
}
82
107
83
108
" rollback to savepoint" in {
84
- withHandler { handler =>
85
- executeDdl(handler, tableCreate)
86
- await(handler.inTransaction { conn =>
87
- conn.sendQuery(tableInsert(1 )).flatMap { _ =>
88
- conn.sendQuery(" SAVEPOINT one" ).flatMap { _ =>
89
- conn.sendQuery(tableInsert(2 )).flatMap { _ =>
90
- conn.sendQuery(" ROLLBACK TO SAVEPOINT one" )
109
+ withHandler {
110
+ handler =>
111
+ executeDdl(handler, tableCreate)
112
+ await(handler.inTransaction {
113
+ conn =>
114
+ conn.sendQuery(tableInsert(1 )).flatMap {
115
+ _ =>
116
+ conn.sendQuery(" SAVEPOINT one" ).flatMap {
117
+ _ =>
118
+ conn.sendQuery(tableInsert(2 )).flatMap {
119
+ _ =>
120
+ conn.sendQuery(" ROLLBACK TO SAVEPOINT one" )
121
+ }
122
+ }
91
123
}
92
- }
93
- }
94
- })
124
+ })
95
125
96
- val rows = executeQuery(handler, tableSelect).rows.get
97
- rows.length === 1
98
- rows(0 )(0 ) === 1
126
+ val rows = executeQuery(handler, tableSelect).rows.get
127
+ rows.length === 1
128
+ rows(0 )(0 ) === 1
99
129
}
100
130
101
131
}
0 commit comments