如何在 propel 中创建一个新的事务范围
How to create a new transaction scope in propel
我们在 mysql 数据库上使用 propel 作为 orm。
我们正在更改几个 table 并在事务期间调用外部服务。在此期间,我们将这些操作和响应记录在日志 table 中。如果发生错误,我们会恢复操作但希望保留日志消息。目前,日志消息正在使用相同的事务范围,并将随事务一起还原。
我是否通过
获得新的连接和事务范围
$con = Propel::getConnection(DATABASE_NAME);
或者我是否必须检查是否返回相同的连接
伪代码
public function write_log()
{
$con = Propel::getConnection(DATABASE_NAME);
$log=new Log();
$log->message('foo');
$log->save($con);
}
public function change_data()
{
write_log('start');
$con = Propel::getConnection(DATABASE_NAME);
$con->beginTransaction();
try {
//this message should stay in the database
write_log('change_db_data:'.$new_db_value);
//this should be reverted
change_db_data($new_db_value);
write_log('call webservice_1');
$response=call_webservice_1();
write_log($response);
if($response==null)
{
$con->rollback();
}
write_log('call webservice_2');
$response=call_webservice_2();
write_log($response);
if($response==null)
{
$con->rollback();
}
$con->commit();
}
catch(Exception $e){
$con->rollback();
write_log('error')
}
write_log('end');
}
选择 Propel 是个不错的选择。您有两种选择,要么将日志记录封装在自己的事务中,要么使用 Propel 独特支持的嵌套事务。
第一个只需要 write_log 函数中的事务性:
public function write_log()
{
$con = Propel::getConnection(DATABASE_NAME);
$con->beginTransaction();
$log=new Log();
$log->message('foo');
$log->save($con);
$con->commit();
}
二是开启嵌套事务,保证只回滚内层事务:
public function write_log()
{
$con = Propel::getConnection(DATABASE_NAME);
$log=new Log();
$log->message('foo');
$log->save($con);
}
public function change_data()
{
$con = Propel::getConnection(DATABASE_NAME);
$con->beginTransaction();
write_log('start');
$con->beginTransaction();
try {
//this message should stay in the database
write_log('change_db_data:'.$new_db_value);
//this should be reverted
change_db_data($new_db_value);
write_log('call webservice_1');
$response=call_webservice_1();
write_log($response);
if($response==null)
{
throw new \Exception('Null response.');
}
write_log('call webservice_2');
$response=call_webservice_2();
write_log($response);
if($response==null)
{
throw new \Exception('Null response.');
}
$con->commit();
}
catch(Exception $e){
$con->rollback();
write_log('error')
}
write_log('end');
$con->commit();
}
我们在 mysql 数据库上使用 propel 作为 orm。 我们正在更改几个 table 并在事务期间调用外部服务。在此期间,我们将这些操作和响应记录在日志 table 中。如果发生错误,我们会恢复操作但希望保留日志消息。目前,日志消息正在使用相同的事务范围,并将随事务一起还原。
我是否通过
获得新的连接和事务范围$con = Propel::getConnection(DATABASE_NAME);
或者我是否必须检查是否返回相同的连接
伪代码
public function write_log()
{
$con = Propel::getConnection(DATABASE_NAME);
$log=new Log();
$log->message('foo');
$log->save($con);
}
public function change_data()
{
write_log('start');
$con = Propel::getConnection(DATABASE_NAME);
$con->beginTransaction();
try {
//this message should stay in the database
write_log('change_db_data:'.$new_db_value);
//this should be reverted
change_db_data($new_db_value);
write_log('call webservice_1');
$response=call_webservice_1();
write_log($response);
if($response==null)
{
$con->rollback();
}
write_log('call webservice_2');
$response=call_webservice_2();
write_log($response);
if($response==null)
{
$con->rollback();
}
$con->commit();
}
catch(Exception $e){
$con->rollback();
write_log('error')
}
write_log('end');
}
选择 Propel 是个不错的选择。您有两种选择,要么将日志记录封装在自己的事务中,要么使用 Propel 独特支持的嵌套事务。
第一个只需要 write_log 函数中的事务性:
public function write_log()
{
$con = Propel::getConnection(DATABASE_NAME);
$con->beginTransaction();
$log=new Log();
$log->message('foo');
$log->save($con);
$con->commit();
}
二是开启嵌套事务,保证只回滚内层事务:
public function write_log()
{
$con = Propel::getConnection(DATABASE_NAME);
$log=new Log();
$log->message('foo');
$log->save($con);
}
public function change_data()
{
$con = Propel::getConnection(DATABASE_NAME);
$con->beginTransaction();
write_log('start');
$con->beginTransaction();
try {
//this message should stay in the database
write_log('change_db_data:'.$new_db_value);
//this should be reverted
change_db_data($new_db_value);
write_log('call webservice_1');
$response=call_webservice_1();
write_log($response);
if($response==null)
{
throw new \Exception('Null response.');
}
write_log('call webservice_2');
$response=call_webservice_2();
write_log($response);
if($response==null)
{
throw new \Exception('Null response.');
}
$con->commit();
}
catch(Exception $e){
$con->rollback();
write_log('error')
}
write_log('end');
$con->commit();
}