1. 程式人生 > 其它 >好玩Spring之同一個類中的巢狀事務試驗

好玩Spring之同一個類中的巢狀事務試驗

技術標籤:springTransacation巢狀事務

試驗

/**
 * 情形一:methodA: PROPAGATION_REQUIRED  methodB: PROPAGATION_REQUIRED(相當於一個事務)
 * 異常條件:無
 * methodA / methodB 均未加try-catch
 *
 * 結果:A_table / B_table 均可以插入資料
 *
 */
/**
 * 情形二:methodA: 沒有加@Transactional  methodB: PROPAGATION_REQUIRED
 * 異常條件:無
 *
 * 結果:A_table / B_table 均沒有插入資料
 *
 * 原因:在呼叫A的時候只建立一個代理類,呼叫B的時候,不是呼叫的代理類,所以@Transactional不生效
 *
 */
/** * 情形三:methodA: PROPAGATION_REQUIRED methodB: 沒有加@Transactional * 異常條件:無 * * 結果:A_table / B_table 均可以插入資料 * * 原因:在呼叫A的時候只建立一個代理類,開啟了事務,呼叫B時,直接使用這個事務 * */ /** * 情形四:methodA: PROPAGATION_REQUIRED methodB: PROPAGATION_REQUIRED(相當於一個事務) * 異常條件:B中有 1/0 異常 * methodA / methodB 均未加try-catch * * 結果:A_table / B_table 均沒有插入資料 * */
/** * 情形五:methodA: PROPAGATION_REQUIRED methodB: PROPAGATION_REQUIRED * 異常條件:B中有 1/0 異常 * methodB 加try-catch * * 結果:A_table / B_table 均可以插入資料 * */ /** * 情形六:methodA: PROPAGATION_REQUIRED methodB: PROPAGATION_REQUIRED * 異常條件:B中有 1/0 異常 * methodA 加try-catch * * 結果:A_table / B_table 均沒有插入資料 * */
public class JdbcFooRepository { private DataSource dataSource; public JdbcFooRepository(DataSource dataSource) { this.dataSource = dataSource; } @Transactional(transactionManager = "txManager") public void methodA() { JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); Connection connection = DataSourceUtils.getConnection(dataSource); try { connection.setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } try { jdbcTemplate.execute("insert into A_table(title, author) values('A_title1', 'A_author1')"); methodB(jdbcTemplate); } catch (DataAccessException e) { e.printStackTrace(); } } public void methodB(JdbcTemplate jdbcTemplate) { jdbcTemplate.execute("insert into B_table(title, author) values('B_title1', 'B_author1')"); int i = 1/0; } }

結論

前提:methodA和methodB處於同一個類中,事務的傳播屬性均為:PROPAGATION_REQUIRED
在這裡插入圖片描述

題目

// 有個面試題如下:
	// B_title中,id=100的記錄沒有,問insert語句是否可以執行成功?
	// 答:可以執行成功,id=100的記錄沒有,但語句可以正常執行,不會報錯

	@Transactional(transactionManager = "txManager")
	public void C() {
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		Connection connection = DataSourceUtils.getConnection(dataSource);
		try {
			connection.setAutoCommit(false);
		} catch (SQLException e) {
			e.printStackTrace();
		}


		try {
			jdbcTemplate.execute("insert into A_table(title, author) values('A_title1', 'A_author1')");

			jdbcTemplate.execute("update B_table set title = 'B_title111' where id=100");

		} catch (DataAccessException e) {
			e.printStackTrace();
		}
	}