溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

什么是SpringBoot事務(wù)

發(fā)布時(shí)間:2020-07-14 14:17:44 來(lái)源:億速云 閱讀:273 作者:Leah 欄目:MySQL數(shù)據(jù)庫(kù)

什么是SpringBoot事務(wù)?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

                                                           重要概念

自動(dòng)提交模式

對(duì)于mysql數(shù)據(jù)庫(kù),默認(rèn)情況下,數(shù)據(jù)庫(kù)處于自動(dòng)提交模式。每一條語(yǔ)句處于一個(gè)單獨(dú)的事務(wù)中,在這條語(yǔ)句執(zhí)行完畢時(shí),如果執(zhí)行成功則隱式的提交事務(wù),如果執(zhí)行失敗則隱式的回滾事務(wù)。對(duì)于正常的事務(wù)管理,是一組相關(guān)的操作處于一個(gè)事務(wù)之中,因此必須關(guān)閉數(shù)據(jù)庫(kù)的自動(dòng)提交模式,下面是查看方式:

查看是否自動(dòng)提交命令(ON表示開(kāi)啟自動(dòng)提交,值為1,OFF表示關(guān)閉自動(dòng)提交,值為0):

show variables like 'autocommit';

關(guān)閉自動(dòng)提交后,則用戶將一直處于某個(gè)事務(wù)中,直到執(zhí)行一條commit提交或rollback語(yǔ)句才會(huì)結(jié)束當(dāng)前事務(wù)重新開(kāi)始一個(gè)新的事務(wù)。

DataSource connection = masterDataSource.getConnection();
connection.setAutoCommit(false);

事務(wù)隔離級(jí)別

隔離級(jí)別是指若干個(gè)并發(fā)的事務(wù)之間的隔離程度。TransactionDefinition 接口中定義了五個(gè)表示隔離級(jí)別的常量:

1、TransactionDefinition.ISOLATION_DEFAULT:這是默認(rèn)值,表示使用底層數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別。對(duì)大部分?jǐn)?shù)據(jù)庫(kù)而言,通常這值就是TransactionDefinition.ISOLATION_READ_COMMITTED。

2、TransactionDefinition.ISOLATION_READ_UNCOMMITTED:該隔離級(jí)別表示一個(gè)事務(wù)可以讀取另一個(gè)事務(wù)修改但還沒(méi)有提交的數(shù)據(jù)。該級(jí)別不能防止臟讀,不可重復(fù)讀和幻讀,因此很少使用該隔離級(jí)別。比如PostgreSQL實(shí)際上并沒(méi)有此級(jí)別。

3、TransactionDefinition.ISOLATION_READ_COMMITTED:該隔離級(jí)別表示一個(gè)事務(wù)只能讀取另一個(gè)事務(wù)已經(jīng)提交的數(shù)據(jù)。該級(jí)別可以防止臟讀,這也是大多數(shù)情況下的推薦值。

4、TransactionDefinition.ISOLATION_REPEATABLE_READ:該隔離級(jí)別表示一個(gè)事務(wù)在整個(gè)過(guò)程中可以多次重復(fù)執(zhí)行某個(gè)查詢,并且每次返回的記錄都相同。該級(jí)別可以防止臟讀和不可重復(fù)讀。

5、TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事務(wù)依次逐個(gè)執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾,也就是說(shuō),該級(jí)別可以防止臟讀、不可重復(fù)讀以及幻讀。但是這將嚴(yán)重影響程序的性能。通常情況下也不會(huì)用到該級(jí)別。

事務(wù)傳播行為

所謂事務(wù)的傳播行為是指,如果在開(kāi)始當(dāng)前事務(wù)之前,一個(gè)事務(wù)上下文已經(jīng)存在,此時(shí)有若干選項(xiàng)可以指定一個(gè)事務(wù)性方法的執(zhí)行行為。在TransactionDefinition定義中包括了如下幾個(gè)表示傳播行為的常量:

1、TransactionDefinition.PROPAGATION_REQUIRED:如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒(méi)有事務(wù),則創(chuàng)建一個(gè)新的事務(wù)。這是默認(rèn)值。

2、TransactionDefinition.PROPAGATION_REQUIRES_NEW:創(chuàng)建一個(gè)新的事務(wù),如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。

3、TransactionDefinition.PROPAGATION_SUPPORTS:如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒(méi)有事務(wù),則以非事務(wù)的方式繼續(xù)運(yùn)行。

4、TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。

5、TransactionDefinition.PROPAGATION_NEVER:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異常。

6、TransactionDefinition.PROPAGATION_MANDATORY:如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒(méi)有事務(wù),則拋出異常。

7、TransactionDefinition.PROPAGATION_NESTED:如果當(dāng)前存在事務(wù),則創(chuàng)建一個(gè)事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來(lái)運(yùn)行;如果當(dāng)前沒(méi)有事務(wù),則該取值等價(jià)于TransactionDefinition.PROPAGATION_REQUIRED。

保護(hù)點(diǎn)(Savepoints

首先要知道savepoint就是為回退做的,savepoint的個(gè)數(shù)沒(méi)有限制,savepoint和虛擬機(jī)中快照類似. savepoint是事務(wù)中的一點(diǎn)。用于取消部分事務(wù),當(dāng)結(jié)束事務(wù)時(shí),會(huì)自動(dòng)的刪除該事務(wù)中所定義的所有保存點(diǎn)。

當(dāng)執(zhí)行rollback時(shí),通過(guò)指定保存點(diǎn)可以回退到指定的點(diǎn)。

回退事務(wù)的幾個(gè)重要操作

1、設(shè)置保存點(diǎn) savepoint a

2、取消保存點(diǎn)a之后事務(wù) rollback to a

3、取消全部事務(wù) rollback

注意:這個(gè)回退事務(wù),必須是沒(méi)有commit前使用的;

public class UserRepository {
 
	
	private DataSource masterDataSource;
	private Connection connection = null;
	@Autowired
	public void setMasterDataSource(DataSource masterDataSource) {
		this.masterDataSource = masterDataSource;
	}
 
 
	@Transactional
	public boolean save(User user) {
		try {
			connection = masterDataSource.getConnection();
			connection.setAutoCommit(false);
			//設(shè)置保護(hù)點(diǎn)
			Savepoint saveUser = connection.setSavepoint("saveUser");
			PreparedStatement prepareStatement = connection.prepareStatement("insert into user(id,name,age) values(?,?,?)");
			prepareStatement.setLong(1, user.getId());
			prepareStatement.setString(2, user.getName());
			prepareStatement.setInt(3, user.getAge());
			prepareStatement.execute();
		
			try {
				update(user);
			} catch (Exception e) {
				System.out.println("出錯(cuò)了。。"+e);
				//回滾至保護(hù)點(diǎn)
				connection.rollback(saveUser);
			}
			connection.commit();
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		return true;
	}
	
	public boolean update(User user) {
		System.out.println("save user:"+user);
		
		try {
			PreparedStatement prepareStatement = connection.prepareStatement("update user set name = ? ,age = ? where id = ?)");
			prepareStatement.setLong(3, user.getId());
			prepareStatement.setString(1, "王大拿");
			prepareStatement.setInt(2, 100/0);
			prepareStatement.execute();
			
			connection.commit();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return true;
	}
}

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI