事務的概念就不介紹了, 它的目的是解決ACID問題.html
根據上面兩點能夠得出, 若是你在INNODB事務引擎下, 而且autocommit=1 (默認值), 答案是會, 不然不會. 其餘引擎不支持事務, 這個問題也不存在.mysql
簡而言之, 由於你須要ACID中的CI: consistency && isolatedspring
Mysql是不支持嵌套事務的,開啓了一個事務的狀況下,再開啓一個事務,會隱式的提交上一個事務. 因此咱們就要在系統架構層面來支持事務的嵌套, 常見的作法就是SAVEPOINT.數據庫
PHP框架THINKPHP5的嵌套事務處理策略: 若是開啓了supportSavepoint, 則利用SAVEPOINT來等價子事務, 不然啥也不幹, MySQL驅動下默認開啓bash
/**
* 啓動事務
* @access public
* @return void
* @throws \PDOException
* @throws \Exception
*/
public function startTrans()
{
$this->initConnect(true);
if (!$this->linkID) {
return false;
}
++$this->transTimes;
try {
// 第一個事務, 向mysql發起執行事務 begin
if (1 == $this->transTimes) {
$this->linkID->beginTransaction();
// 非第一個事務, 向mysql添加 SAVEPOINT
} elseif ($this->transTimes > 1 && $this->supportSavepoint()) {
$this->linkID->exec(
$this->parseSavepoint('trans' . $this->transTimes)
);
}
} catch (\Exception $e) {
if ($this->isBreak($e)) {
--$this->transTimes;
return $this->close()->startTrans();
}
throw $e;
}
}
複製代碼
/**
* 用於非自動提交狀態下面的查詢提交
* @access public
* @return void
* @throws PDOException
*/
public function commit()
{
$this->initConnect(true);
// 只有第一個事務才真正發起提交
if (1 == $this->transTimes) {
$this->linkID->commit();
}
--$this->transTimes;
}
複製代碼
/**
* 事務回滾
* @access public
* @return void
* @throws PDOException
*/
public function rollback()
{
$this->initConnect(true);
// 只有第一個事務才真正發起回滾
if (1 == $this->transTimes) {
$this->linkID->rollBack();
// 不然回到保存點
} elseif ($this->transTimes > 1 && $this->supportSavepoint()) {
$this->linkID->exec(
$this->parseSavepointRollBack('trans' . $this->transTimes)
);
}
$this->transTimes = max(0, $this->transTimes - 1);
}
複製代碼
這產生了一個很重要的結論: 子事務的回滾不會致使事務回滾, 只有第一個事務的回滾纔是真正的ROLLBACK架構
Java的spring提供更豐富的嵌套行爲, 而且定義爲事務傳播行爲,同時底層也是利用了SAVEPOINT, 默認值爲 Propagation.REQUIRED。能夠手動指定其餘的事務傳播行爲,總共有七種, 以下:框架
Propagation.REQUIRED 若是當前存在事務,則加入該事務,若是當前不存在事務,則建立一個新的事務。ui
Propagation.SUPPORTS 若是當前存在事務,則加入該事務;若是當前不存在事務,則以非事務的方式繼續運行。this
Propagation.MANDATORY 若是當前存在事務,則加入該事務;若是當前不存在事務,則拋出異常。
Propagation.REQUIRES_NEW 從新建立一個新的事務,若是當前存在事務,延緩當前的事務。
Propagation.NOT_SUPPORTED 以非事務的方式運行,若是當前存在事務,暫停當前的事務。
Propagation.NEVER 以非事務的方式運行,若是當前存在事務,則拋出異常。
Propagation.NESTED 若是沒有,就新建一個事務;若是有,就在當前事務中嵌套其餘事務。