@@ -94,3 +94,50 @@ pub async fn create_user(
94
94
Ok (())
95
95
}
96
96
```
97
+
98
+ ## Using a Guard
99
+
100
+ When a single transaction may be used across function calls,
101
+ or when either a transaction or the database itself may be passed to
102
+ these functions, a ` TransactionGuard ` can be used. It can be
103
+ retrieved by an ` Executor ` , which is implemented by both the
104
+ ` Transaction ` and ` Database ` . The guard is responsible for
105
+ committing the transaction if necessary; since mid-transaction
106
+ commits are not supported, this is a no-op when the guard was
107
+ created from a transaction and will perform the commit if the
108
+ guard was created from a database.
109
+
110
+ ``` rust
111
+ async fn create_user (username : String , exe : impl Executor <'_ >) -> Result <(), rorm :: Error > {
112
+ // The guard will either be a new transaction or an
113
+ // existing one, depending on the Executor
114
+ let mut guard = exe . ensure_transaction (). await ? ;
115
+
116
+ // It can be used very similar to a normal transaction
117
+ // through `get_transaction`
118
+ insert! (guard . get_transaction (), UserInsert )
119
+ . return_primary_key ()
120
+ . single (& UserInsert { username })
121
+ . await ? ;
122
+
123
+ guard . commit ()? ;
124
+ Ok (())
125
+ }
126
+
127
+ async fn test_double_creation (db : & Database ) -> Result <(), rorm : Error > {
128
+ // Start a transaction
129
+ let mut tx = db . start_transaction (). await ? ;
130
+
131
+ // The first call will work but not commit the transaction
132
+ create_user (" username" . to_string (), & mut tx ). await ? ;
133
+
134
+ // The second call will also work but not commit the transaction
135
+ create_user (" another username" . to_string (), & mut tx ). await ? ;
136
+
137
+ // Commit the transaction, since the guard's commit
138
+ // in `create_user` is a no-op there
139
+ tx . commit (). await ? ;
140
+
141
+ Ok (())
142
+ }
143
+ ```
0 commit comments