Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
79b79909
Commit
79b79909
authored
Dec 12, 2007
by
romanb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored transactions. Fixed #464.
parent
b309933a
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
141 additions
and
71 deletions
+141
-71
Collection.php
lib/Doctrine/Collection.php
+2
-2
Connection.php
lib/Doctrine/Connection.php
+6
-1
UnitOfWork.php
lib/Doctrine/Connection/UnitOfWork.php
+2
-2
Transaction.php
lib/Doctrine/Transaction.php
+85
-52
673TestCase.php
tests/Ticket/673TestCase.php
+1
-1
TransactionTestCase.php
tests/TransactionTestCase.php
+15
-11
FutureTestCase.php
tests/Validator/FutureTestCase.php
+1
-1
ValidatorTestCase.php
tests/ValidatorTestCase.php
+28
-0
run.php
tests/run.php
+1
-1
No files found.
lib/Doctrine/Collection.php
View file @
79b79909
...
...
@@ -788,7 +788,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$conn
=
$this
->
_table
->
getConnection
();
}
$conn
->
beginTransaction
();
$conn
->
begin
Internal
Transaction
();
$conn
->
transaction
->
addCollection
(
$this
);
...
...
@@ -817,7 +817,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$conn
=
$this
->
_table
->
getConnection
();
}
$conn
->
beginTransaction
();
$conn
->
begin
Internal
Transaction
();
$conn
->
transaction
->
addCollection
(
$this
);
foreach
(
$this
as
$key
=>
$record
)
{
...
...
lib/Doctrine/Connection.php
View file @
79b79909
...
...
@@ -1114,7 +1114,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/
public
function
flush
()
{
$this
->
beginTransaction
();
$this
->
begin
Internal
Transaction
();
$this
->
unitOfWork
->
saveAll
();
$this
->
commit
();
}
...
...
@@ -1275,6 +1275,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$this
->
transaction
->
beginTransaction
(
$savepoint
);
}
public
function
beginInternalTransaction
(
$savepoint
=
null
)
{
$this
->
transaction
->
beginInternalTransaction
(
$savepoint
);
}
/**
* commit
* Commit the database changes done during a transaction that is in
...
...
lib/Doctrine/Connection/UnitOfWork.php
View file @
79b79909
...
...
@@ -149,7 +149,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$record
->
state
(
Doctrine_Record
::
STATE_LOCKED
);
$conn
->
beginTransaction
();
$conn
->
begin
Internal
Transaction
();
$saveLater
=
$this
->
saveRelated
(
$record
);
$record
->
state
(
$state
);
...
...
@@ -260,7 +260,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
if
(
!
$record
->
exists
())
{
return
false
;
}
$this
->
conn
->
beginTransaction
();
$this
->
conn
->
begin
Internal
Transaction
();
$event
=
new
Doctrine_Event
(
$record
,
Doctrine_Event
::
RECORD_DELETE
);
...
...
lib/Doctrine/Transaction.php
View file @
79b79909
...
...
@@ -50,9 +50,21 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
const
STATE_BUSY
=
2
;
/**
* @var integer $transactionLevel the nesting level of transactions, used by transaction methods
* @var integer $_nestingLevel The current nesting level of this transaction.
* A nesting level of 0 means there is currently no active
* transaction.
*/
protected
$transactionLevel
=
0
;
protected
$_nestingLevel
=
0
;
/**
* @var integer $_internalNestingLevel The current internal nesting level of this transaction.
* "Internal" means transactions started by Doctrine itself.
* Therefore the internal nesting level is always
* lower or equal to the overall nesting level.
* A level of 0 means there is currently no active
* transaction that was initiated by Doctrine itself.
*/
protected
$_internalNestingLevel
=
0
;
/**
* @var array $invalid an array containing all invalid records within this transaction
...
...
@@ -90,14 +102,14 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
/**
* getState
* returns the state of this
connection
* returns the state of this
transaction module.
*
* @see Doctrine_Connection_Transaction::STATE_* constants
* @return integer the connection state
*/
public
function
getState
()
{
switch
(
$this
->
transaction
Level
)
{
switch
(
$this
->
_nesting
Level
)
{
case
0
:
return
Doctrine_Transaction
::
STATE_SLEEP
;
break
;
...
...
@@ -132,7 +144,8 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
*
* @return array An array of invalid records
*/
public
function
getInvalid
(){
public
function
getInvalid
()
{
return
$this
->
invalid
;
}
...
...
@@ -144,20 +157,7 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
*/
public
function
getTransactionLevel
()
{
return
$this
->
transactionLevel
;
}
/**
* getTransactionLevel
* set the current transaction nesting level
*
* @return Doctrine_Transaction this object
*/
public
function
setTransactionLevel
(
$level
)
{
$this
->
transactionLevel
=
$level
;
return
$this
;
return
$this
->
_nestingLevel
;
}
/**
...
...
@@ -167,6 +167,9 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
* if trying to set a savepoint and there is no active transaction
* a new transaction is being started
*
* This method should only be used by userland-code to initiate transactions.
* To initiate a transaction from inside Doctrine use {@link beginInternalTransaction()}.
*
* Listeners: onPreTransactionBegin, onTransactionBegin
*
* @param string $savepoint name of a savepoint to set
...
...
@@ -192,7 +195,7 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
$listener
->
postSavepointCreate
(
$event
);
}
else
{
if
(
$this
->
transaction
Level
==
0
)
{
if
(
$this
->
_nesting
Level
==
0
)
{
$event
=
new
Doctrine_Event
(
$this
,
Doctrine_Event
::
TX_BEGIN
);
$listener
->
preTransactionBegin
(
$event
);
...
...
@@ -200,7 +203,7 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
if
(
!
$event
->
skipOperation
)
{
try
{
$this
->
conn
->
getDbh
()
->
beginTransaction
();
}
catch
(
Exception
$e
)
{
}
catch
(
Exception
$e
)
{
throw
new
Doctrine_Transaction_Exception
(
$e
->
getMessage
());
}
}
...
...
@@ -208,7 +211,7 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
}
}
$level
=
++
$this
->
transaction
Level
;
$level
=
++
$this
->
_nesting
Level
;
return
$level
;
}
...
...
@@ -228,16 +231,16 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
*/
public
function
commit
(
$savepoint
=
null
)
{
$this
->
conn
->
connect
();
if
(
$this
->
transactionLevel
==
0
)
{
return
false
;
if
(
$this
->
_nestingLevel
==
0
)
{
throw
new
Doctrine_Transaction_Exception
(
"Commit failed. There is no active transaction."
);
}
$this
->
conn
->
connect
();
$listener
=
$this
->
conn
->
getAttribute
(
Doctrine
::
ATTR_LISTENER
);
if
(
!
is_null
(
$savepoint
))
{
$this
->
transaction
Level
-=
$this
->
removeSavePoints
(
$savepoint
);
$this
->
_nesting
Level
-=
$this
->
removeSavePoints
(
$savepoint
);
$event
=
new
Doctrine_Event
(
$this
,
Doctrine_Event
::
SAVEPOINT_COMMIT
);
...
...
@@ -249,13 +252,19 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
$listener
->
postSavepointCommit
(
$event
);
}
else
{
if
(
$this
->
transactionLevel
==
1
)
{
if
(
$this
->
_nestingLevel
==
1
||
$this
->
_internalNestingLevel
==
1
)
{
if
(
!
empty
(
$this
->
invalid
))
{
if
(
$this
->
_internalNestingLevel
==
1
)
{
// transaction was started by doctrine, so we are responsible
// for a rollback
$this
->
rollback
();
$tmp
=
$this
->
invalid
;
$this
->
invalid
=
array
();
throw
new
Doctrine_Validator_Exception
(
$tmp
);
}
}
if
(
$this
->
_nestingLevel
==
1
)
{
// take snapshots of all collections used within this transaction
foreach
(
$this
->
_collections
as
$coll
)
{
$coll
->
takeSnapshot
();
...
...
@@ -269,10 +278,15 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
$this
->
conn
->
getDbh
()
->
commit
();
}
$listener
->
postTransactionCommit
(
$event
);
}
}
$this
->
transactionLevel
--
;
if
(
$this
->
_nestingLevel
>
0
)
{
$this
->
_nestingLevel
--
;
}
if
(
$this
->
_internalNestingLevel
>
0
)
{
$this
->
_internalNestingLevel
--
;
}
}
return
true
;
...
...
@@ -300,17 +314,22 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
*/
public
function
rollback
(
$savepoint
=
null
)
{
if
(
$this
->
_nestingLevel
==
0
)
{
throw
new
Doctrine_Transaction_Exception
(
"Rollback failed. There is no active transaction."
);
}
$this
->
conn
->
connect
();
$currentState
=
$this
->
getState
();
if
(
$currentState
!=
self
::
STATE_ACTIVE
&&
$currentState
!=
self
::
STATE_BUSY
)
{
if
(
$this
->
_internalNestingLevel
>
1
||
$this
->
_nestingLevel
>
1
)
{
$this
->
_internalNestingLevel
--
;
$this
->
_nestingLevel
--
;
return
false
;
}
$listener
=
$this
->
conn
->
getAttribute
(
Doctrine
::
ATTR_LISTENER
);
if
(
!
is_null
(
$savepoint
))
{
$this
->
transaction
Level
-=
$this
->
removeSavePoints
(
$savepoint
);
$this
->
_nesting
Level
-=
$this
->
removeSavePoints
(
$savepoint
);
$event
=
new
Doctrine_Event
(
$this
,
Doctrine_Event
::
SAVEPOINT_ROLLBACK
);
...
...
@@ -327,7 +346,8 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
$listener
->
preTransactionRollback
(
$event
);
if
(
!
$event
->
skipOperation
)
{
$this
->
transactionLevel
=
0
;
$this
->
_nestingLevel
=
0
;
$this
->
_internalNestingLevel
=
0
;
try
{
$this
->
conn
->
getDbh
()
->
rollback
();
}
catch
(
Exception
$e
)
{
...
...
@@ -450,4 +470,17 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
{
throw
new
Doctrine_Transaction_Exception
(
'Fetching transaction isolation level not supported by this driver.'
);
}
/**
* Initiates a transaction.
*
* This method must only be used by Doctrine itself to initiate transactions.
* Userland-code must use {@link beginTransaction()}.
*/
public
function
beginInternalTransaction
(
$savepoint
=
null
)
{
$this
->
_internalNestingLevel
++
;
return
$this
->
beginTransaction
(
$savepoint
);
}
}
tests/Ticket/673TestCase.php
View file @
79b79909
...
...
@@ -44,7 +44,7 @@ class Doctrine_Ticket_673_TestCase extends Doctrine_UnitTestCase
->
delete
()
->
from
(
'T673_Student s'
)
->
where
(
's.name = ? AND s.foo < ?'
,
'foo'
,
3
);
var_dump
(
$q
->
getSql
());
$this
->
assertTrue
(
preg_match_all
(
'/(s_name)/'
,
$q
->
getSql
(),
$m
)
===
1
);
$this
->
assertTrue
(
preg_match_all
(
'/(s_foo)/'
,
$q
->
getSql
(),
$m
)
===
1
);
...
...
tests/TransactionTestCase.php
View file @
79b79909
...
...
@@ -121,27 +121,21 @@ class Doctrine_Transaction_TestCase extends Doctrine_UnitTestCase
public
function
testReleaseSavepointIsOnlyImplementedAtDriverLevel
()
{
try
{
$this
->
transaction
->
setTransactionLevel
(
1
);
$this
->
transaction
->
commit
(
'savepoint'
);
$this
->
fail
();
}
catch
(
Doctrine_Transaction_Exception
$e
)
{
}
catch
(
Doctrine_Transaction_Exception
$e
)
{
$this
->
pass
();
}
$this
->
transaction
->
setTransactionLevel
(
0
);
}
public
function
testRollbackSavepointIsOnlyImplementedAtDriverLevel
()
{
try
{
$this
->
transaction
->
setTransactionLevel
(
1
);
$this
->
transaction
->
rollback
(
'savepoint'
);
$this
->
fail
();
}
catch
(
Doctrine_Transaction_Exception
$e
)
{
$this
->
pass
();
}
$this
->
transaction
->
setTransactionLevel
(
0
);
}
public
function
testSetIsolationIsOnlyImplementedAtDriverLevel
()
...
...
@@ -174,14 +168,24 @@ class Doctrine_Transaction_TestCase extends Doctrine_UnitTestCase
$this
->
assertEqual
(
$this
->
transaction
->
getState
(),
Doctrine_Transaction
::
STATE_SLEEP
);
}
public
function
testCommitting
NotActiveTransactionReturnsFalse
()
public
function
testCommitting
WithNoActiveTransactionThrowsException
()
{
$this
->
assertEqual
(
$this
->
transaction
->
commit
(),
false
);
try
{
$this
->
transaction
->
commit
();
$this
->
fail
();
}
catch
(
Doctrine_Transaction_Exception
$e
)
{
$this
->
pass
();
}
}
public
function
testExceptionIsThrownWhenUsingRollbackOnNotActiveTransaction
()
{
$this
->
assertEqual
(
$this
->
transaction
->
rollback
(),
false
);
try
{
$this
->
transaction
->
rollback
();
$this
->
fail
();
}
catch
(
Doctrine_Transaction_Exception
$e
)
{
$this
->
pass
();
}
}
public
function
testBeginTransactionStartsNewTransaction
()
...
...
tests/Validator/FutureTestCase.php
View file @
79b79909
tests/ValidatorTestCase.php
View file @
79b79909
...
...
@@ -397,4 +397,32 @@ class Doctrine_Validator_TestCase extends Doctrine_UnitTestCase
$this
->
manager
->
setAttribute
(
Doctrine
::
ATTR_VALIDATE
,
Doctrine
::
VALIDATE_NONE
);
}
public
function
testSaveInTransactionThrowsValidatorException
()
{
$this
->
manager
->
setAttribute
(
Doctrine
::
ATTR_VALIDATE
,
Doctrine
::
VALIDATE_ALL
);
try
{
$this
->
conn
->
beginTransaction
();
$client
=
new
ValidatorTest_ClientModel
();
$client
->
short_name
=
'test'
;
$client
->
ValidatorTest_AddressModel
[
0
]
->
state
=
'az'
;
$client
->
save
();
$this
->
fail
();
$this
->
conn
->
commit
();
}
catch
(
Doctrine_Validator_Exception
$dve
)
{
$s
=
$dve
->
getInvalidRecords
();
$this
->
assertEqual
(
1
,
count
(
$dve
->
getInvalidRecords
()));
$stack
=
$client
->
ValidatorTest_AddressModel
[
0
]
->
getErrorStack
();
$this
->
assertTrue
(
in_array
(
'notnull'
,
$stack
[
'address1'
]));
$this
->
assertTrue
(
in_array
(
'notblank'
,
$stack
[
'address1'
]));
$this
->
assertTrue
(
in_array
(
'notnull'
,
$stack
[
'address2'
]));
$this
->
assertTrue
(
in_array
(
'notnull'
,
$stack
[
'city'
]));
$this
->
assertTrue
(
in_array
(
'notblank'
,
$stack
[
'city'
]));
$this
->
assertTrue
(
in_array
(
'usstate'
,
$stack
[
'state'
]));
$this
->
assertTrue
(
in_array
(
'notnull'
,
$stack
[
'zip'
]));
$this
->
assertTrue
(
in_array
(
'notblank'
,
$stack
[
'zip'
]));
}
$this
->
manager
->
setAttribute
(
Doctrine
::
ATTR_VALIDATE
,
Doctrine
::
VALIDATE_NONE
);
}
}
tests/run.php
View file @
79b79909
...
...
@@ -153,7 +153,7 @@ $test->addTestCase($data_types);
// Utility components
$plugins
=
new
GroupTest
(
'Plugin tests: View, Validator, Hook'
,
'plugins'
);
//$utility->addTestCase(new Doctrine_PessimisticLocking_TestCase());
$plugins
->
addTestCase
(
new
Doctrine_Plugin_TestCase
());
//
$plugins->addTestCase(new Doctrine_Plugin_TestCase());
$plugins
->
addTestCase
(
new
Doctrine_View_TestCase
());
$plugins
->
addTestCase
(
new
Doctrine_AuditLog_TestCase
());
$plugins
->
addTestCase
(
new
Doctrine_Validator_TestCase
());
...
...
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