Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Rotua Panjaitan
yii2
Commits
e5195937
Commit
e5195937
authored
Jul 10, 2014
by
Ragazzo
Committed by
Alexander Makarov
Jul 10, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixes #3384: Added callback-style transactions
parent
9c2e7661
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
90 additions
and
0 deletions
+90
-0
CHANGELOG.md
framework/CHANGELOG.md
+1
-0
Connection.php
framework/db/Connection.php
+44
-0
ConnectionTest.php
tests/unit/framework/db/ConnectionTest.php
+45
-0
No files found.
framework/CHANGELOG.md
View file @
e5195937
...
...
@@ -99,6 +99,7 @@ Yii Framework 2 Change Log
-
Enh #3298: Supported configuring
`View::theme`
using a class name (netyum, qiangxue)
-
Enh #3328:
`BaseMailer`
generates better text body from html body (armab)
-
Enh #3380: Allow
`value`
in
`defaultValueValidator`
to be a closure (Alex-Code)
-
Enh #3384: Added callback-style transactions (leandrogehlen, Ragazzo, samdark)
-
Enh #3399, #3241: Added support for MS SQL Server older than 2012 (fourteenmeister, samdark)
-
Enh #3472: Added configurable option to encode spaces in dropDownLists and listBoxes (kartik-v)
-
Enh #3518:
`yii\helpers\Html::encode()`
now replaces invalid code sequences with "�" (DaSourcerer)
...
...
framework/db/Connection.php
View file @
e5195937
...
...
@@ -72,6 +72,26 @@ use yii\caching\Cache;
* }
* ~~~
*
* You also can use shortcut for the above like the following:
*
* ~~~
* $connection->transaction(function() {
* $order = new Order($customer);
* $order->save();
* $order->addItems($items);
* });
* ~~~
*
* If needed you can pass transaction object instance as a second parameter, for example when you need to
* set custom transaction isolation level:
*
* ~~~
* $connection->transaction(function() {
*
* // your code here
* }, $connection->beginTransaction(Transaction::READ_UNCOMMITTED));
* ~~~
*
* Connection is often used as an application component and configured in the application
* configuration like the following:
*
...
...
@@ -439,6 +459,30 @@ class Connection extends Component
}
/**
* Executes callback provided in a transaction.
*
* @param \Closure $callback
* @param string|null $isolationLevel The isolation level to use for this transaction.
* See [[Transaction::begin()]] for details.
* @throws \Exception
* @return mixed result of callback function
*/
public
function
transaction
(
\Closure
$callback
,
$isolationLevel
=
null
)
{
$transaction
=
$this
->
beginTransaction
(
$isolationLevel
);
try
{
$result
=
$callback
();
$transaction
->
commit
();
}
catch
(
\Exception
$e
)
{
$transaction
->
rollBack
();
throw
$e
;
}
return
$result
;
}
/**
* Returns the schema information for the database opened by this connection.
* @return Schema the schema information for the database opened by this connection.
* @throws NotSupportedException if there is no support for the current driver type
...
...
tests/unit/framework/db/ConnectionTest.php
View file @
e5195937
...
...
@@ -121,4 +121,49 @@ class ConnectionTest extends DatabaseTestCase
$transaction
->
commit
();
}
/**
* @expectedException \Exception
*/
public
function
testTransactionShortcutException
()
{
$connection
=
$this
->
getConnection
(
true
);
$connection
->
transaction
(
function
()
use
(
$connection
)
{
$connection
->
createCommand
()
->
insert
(
'profile'
,
[
'description'
=>
'test transaction shortcut'
])
->
execute
();
throw
new
\Exception
(
'Exception in transaction shortcut'
);
});
$profilesCount
=
$connection
->
createCommand
(
"SELECT COUNT(*) FROM profile WHERE description = 'test transaction shortcut';"
)
->
queryScalar
();
$this
->
assertEquals
(
0
,
$profilesCount
,
'profile should not be inserted in transaction shortcut'
);
}
public
function
testTransactionShortcutCorrect
()
{
$connection
=
$this
->
getConnection
(
true
);
$result
=
$connection
->
transaction
(
function
()
use
(
$connection
)
{
$connection
->
createCommand
()
->
insert
(
'profile'
,
[
'description'
=>
'test transaction shortcut'
])
->
execute
();
return
true
;
});
$this
->
assertTrue
(
$result
,
'transaction shortcut valid value should be returned from callback'
);
$profilesCount
=
$connection
->
createCommand
(
"SELECT COUNT(*) FROM profile WHERE description = 'test transaction shortcut';"
)
->
queryScalar
();
$this
->
assertEquals
(
1
,
$profilesCount
,
'profile should be inserted in transaction shortcut'
);
}
public
function
testTransactionShortcutCustom
()
{
$connection
=
$this
->
getConnection
(
true
);
$result
=
$connection
->
transaction
(
function
()
use
(
$connection
)
{
$connection
->
createCommand
()
->
insert
(
'profile'
,
[
'description'
=>
'test transaction shortcut'
])
->
execute
();
return
true
;
},
$connection
->
beginTransaction
(
Transaction
::
READ_UNCOMMITTED
));
$this
->
assertTrue
(
$result
,
'transaction shortcut valid value should be returned from callback'
);
$profilesCount
=
$connection
->
createCommand
(
"SELECT COUNT(*) FROM profile WHERE description = 'test transaction shortcut';"
)
->
queryScalar
();
$this
->
assertEquals
(
1
,
$profilesCount
,
'profile should be inserted in transaction shortcut'
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment