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
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
PSDI Army
yii2
Commits
4727ac8f
Commit
4727ac8f
authored
Aug 07, 2013
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored the feature of transactional operations.
parent
db8233e5
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
58 additions
and
31 deletions
+58
-31
Model.php
framework/yii/base/Model.php
+6
-10
ActiveRecord.php
framework/yii/db/ActiveRecord.php
+52
-21
No files found.
framework/yii/base/Model.php
View file @
4727ac8f
...
...
@@ -8,8 +8,11 @@
namespace
yii\base
;
use
Yii
;
use
ArrayAccess
;
use
ArrayObject
;
use
ArrayIterator
;
use
ReflectionClass
;
use
IteratorAggregate
;
use
yii\helpers\Inflector
;
use
yii\validators\RequiredValidator
;
use
yii\validators\Validator
;
...
...
@@ -42,7 +45,7 @@ use yii\validators\Validator;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
Model
extends
Component
implements
\IteratorAggregate
,
\
ArrayAccess
class
Model
extends
Component
implements
IteratorAggregate
,
ArrayAccess
{
/**
* @event ModelEvent an event raised at the beginning of [[validate()]]. You may set
...
...
@@ -184,7 +187,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
*/
public
function
formName
()
{
$reflector
=
new
\
ReflectionClass
(
$this
);
$reflector
=
new
ReflectionClass
(
$this
);
return
$reflector
->
getShortName
();
}
...
...
@@ -196,7 +199,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
*/
public
function
attributes
()
{
$class
=
new
\
ReflectionClass
(
$this
);
$class
=
new
ReflectionClass
(
$this
);
$names
=
array
();
foreach
(
$class
->
getProperties
(
\ReflectionProperty
::
IS_PUBLIC
)
as
$property
)
{
$name
=
$property
->
getName
();
...
...
@@ -608,9 +611,6 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
return
array
();
}
$attributes
=
array
();
if
(
isset
(
$scenarios
[
$scenario
][
'attributes'
])
&&
is_array
(
$scenarios
[
$scenario
][
'attributes'
]))
{
$scenarios
[
$scenario
]
=
$scenarios
[
$scenario
][
'attributes'
];
}
foreach
(
$scenarios
[
$scenario
]
as
$attribute
)
{
if
(
$attribute
[
0
]
!==
'!'
)
{
$attributes
[]
=
$attribute
;
...
...
@@ -630,11 +630,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
if
(
!
isset
(
$scenarios
[
$scenario
]))
{
return
array
();
}
if
(
isset
(
$scenarios
[
$scenario
][
'attributes'
])
&&
is_array
(
$scenarios
[
$scenario
][
'attributes'
]))
{
$attributes
=
$scenarios
[
$scenario
][
'attributes'
];
}
else
{
$attributes
=
$scenarios
[
$scenario
];
}
foreach
(
$attributes
as
$i
=>
$attribute
)
{
if
(
$attribute
[
0
]
===
'!'
)
{
$attributes
[
$i
]
=
substr
(
$attribute
,
1
);
...
...
framework/yii/db/ActiveRecord.php
View file @
4727ac8f
...
...
@@ -72,20 +72,22 @@ class ActiveRecord extends Model
const
EVENT_AFTER_DELETE
=
'afterDelete'
;
/**
* Represents insert ActiveRecord operation. This constant is used for specifying set of atomic operations
* for particular scenario in the [[scenarios()]] method.
* The insert operation. This is mainly used when overriding [[transactions()]] to specify which operations are transactional.
*/
const
OP_INSERT
=
'insert'
;
const
OP_INSERT
=
0x01
;
/**
* Represents update ActiveRecord operation. This constant is used for specifying set of atomic operations
* for particular scenario in the [[scenarios()]] method.
* The update operation. This is mainly used when overriding [[transactions()]] to specify which operations are transactional.
*/
const
OP_UPDATE
=
'update'
;
const
OP_UPDATE
=
0x02
;
/**
* Represents delete ActiveRecord operation. This constant is used for specifying set of atomic operations
* for particular scenario in the [[scenarios()]] method.
* The delete operation. This is mainly used when overriding [[transactions()]] to specify which operations are transactional.
*/
const
OP_DELETE
=
'delete'
;
const
OP_DELETE
=
0x04
;
/**
* All three operations: insert, update, delete.
* This is a shortcut of the expression: OP_INSERT | OP_UPDATE | OP_DELETE.
*/
const
OP_ALL
=
0x07
;
/**
* @var array attribute values indexed by attribute names
...
...
@@ -331,6 +333,38 @@ class ActiveRecord extends Model
}
/**
* Declares which DB operations should be performed within a transaction in different scenarios.
* The supported DB operations are: [[OP_INSERT]], [[OP_UPDATE]] and [[OP_DELETE]],
* which correspond to the [[insert()]], [[update()]] and [[delete()]] methods, respectively.
* By default, these methods are NOT enclosed in a DB transaction.
*
* In some scenarios, to ensure data consistency, you may want to enclose some or all of them
* in transactions. You can do so by overriding this method and returning the operations
* that need to be transactional. For example,
*
* ~~~
* return array(
* 'admin' => self::OP_INSERT,
* 'api' => self::OP_INSERT | self::OP_UPDATE | self::OP_DELETE,
* // the above is equivalent to the following:
* // 'api' => self::OP_ALL,
*
* );
* ~~~
*
* The above declaration specifies that in the "admin" scenario, the insert operation ([[insert()]])
* should be done in a transaction; and in the "api" scenario, all the operations should be done
* in a transaction.
*
* @return array the declarations of transactional operations. The array keys are scenarios names,
* and the array values are the corresponding transaction operations.
*/
public
function
transactions
()
{
return
array
();
}
/**
* PHP getter magic method.
* This method is overridden so that attributes and related objects can be accessed like properties.
* @param string $name property name
...
...
@@ -712,7 +746,7 @@ class ActiveRecord extends Model
return
false
;
}
$db
=
static
::
getDb
();
$transaction
=
$this
->
is
OperationAtomic
(
self
::
OP_INSERT
)
&&
$db
->
getTransaction
()
===
null
?
$db
->
beginTransaction
()
:
null
;
$transaction
=
$this
->
is
Transactional
(
self
::
OP_INSERT
)
&&
$db
->
getTransaction
()
===
null
?
$db
->
beginTransaction
()
:
null
;
try
{
$result
=
$this
->
insertInternal
(
$attributes
);
if
(
$transaction
!==
null
)
{
...
...
@@ -822,7 +856,7 @@ class ActiveRecord extends Model
return
false
;
}
$db
=
static
::
getDb
();
$transaction
=
$this
->
is
OperationAtomic
(
self
::
OP_UPDATE
)
&&
$db
->
getTransaction
()
===
null
?
$db
->
beginTransaction
()
:
null
;
$transaction
=
$this
->
is
Transactional
(
self
::
OP_UPDATE
)
&&
$db
->
getTransaction
()
===
null
?
$db
->
beginTransaction
()
:
null
;
try
{
$result
=
$this
->
updateInternal
(
$attributes
);
if
(
$transaction
!==
null
)
{
...
...
@@ -929,7 +963,7 @@ class ActiveRecord extends Model
public
function
delete
()
{
$db
=
static
::
getDb
();
$transaction
=
$this
->
is
OperationAtomic
(
self
::
OP_DELETE
)
&&
$db
->
getTransaction
()
===
null
?
$db
->
beginTransaction
()
:
null
;
$transaction
=
$this
->
is
Transactional
(
self
::
OP_DELETE
)
&&
$db
->
getTransaction
()
===
null
?
$db
->
beginTransaction
()
:
null
;
try
{
$result
=
false
;
if
(
$this
->
beforeDelete
())
{
...
...
@@ -1454,17 +1488,14 @@ class ActiveRecord extends Model
}
/**
* @param string $operation possible values are ActiveRecord::INSERT, ActiveRecord::UPDATE and ActiveRecord::DELETE.
* @return boolean whether given operation is atomic. Currently active scenario is taken into account.
* Returns a value indicating whether the specified operation is transactional in the current [[scenario]].
* @param integer $operation the operation to check. Possible values are [[OP_INSERT]], [[OP_UPDATE]] and [[OP_DELETE]].
* @return boolean whether the specified operation is transactional in the current [[scenario]].
*/
p
rivate
function
isOperationAtomic
(
$operation
)
p
ublic
function
isTransactional
(
$operation
)
{
$scenario
=
$this
->
getScenario
();
$scenarios
=
$this
->
scenarios
();
if
(
isset
(
$scenarios
[
$scenario
],
$scenarios
[
$scenario
][
'atomic'
])
&&
is_array
(
$scenarios
[
$scenario
][
'atomic'
]))
{
return
in_array
(
$operation
,
$scenarios
[
$scenario
][
'atomic'
]);
}
else
{
return
false
;
}
$transactions
=
$this
->
transactions
();
return
isset
(
$transactions
[
$scenario
])
&&
(
$transactions
[
$scenario
]
&
$operation
);
}
}
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