JDBC系列:(7)使用Connection操作事務(wù)

事務(wù)ACID特性
序號(hào)特性描述
1原子性(Atomicity)原子性是指事務(wù)是一個(gè)不可分割的工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。
2一致性(Consistency)事務(wù)必須使數(shù)據(jù)庫從一個(gè)一致性狀態(tài)變換到另外一個(gè)一致性狀態(tài)。
3隔離性(Isolation)事務(wù)的隔離性是多個(gè)用戶并發(fā)訪問數(shù)據(jù)庫時(shí),數(shù)據(jù)庫為每一個(gè)用戶開啟的事務(wù),不能被其他事務(wù)的操作數(shù)據(jù)所干擾,多個(gè)并發(fā)事務(wù)之間要相互隔離。
4持久性(Durability)持久性是指一個(gè)事務(wù)一旦被提交,它對(duì)數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的,接下來即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對(duì)其有任何影響



創(chuàng)新互聯(lián)公司是一家以網(wǎng)絡(luò)技術(shù)公司,為中小企業(yè)提供網(wǎng)站維護(hù)、成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、網(wǎng)站備案、服務(wù)器租用、域名申請(qǐng)、軟件開發(fā)、微信小程序等企業(yè)互聯(lián)網(wǎng)相關(guān)業(yè)務(wù),是一家有著豐富的互聯(lián)網(wǎng)運(yùn)營推廣經(jīng)驗(yàn)的科技公司,有著多年的網(wǎng)站建站經(jīng)驗(yàn),致力于幫助中小企業(yè)在互聯(lián)網(wǎng)讓打出自已的品牌和口碑,讓企業(yè)在互聯(lián)網(wǎng)上打開一個(gè)面向全國乃至全球的業(yè)務(wù)窗口:建站歡迎聯(lián)系:18982081108

Connection操作事務(wù)的相關(guān)方法
序號(hào)方法作用
1void setAutoCommit(boolean autoCommit)設(shè)置事務(wù)是否自動(dòng)提交
如果設(shè)置為false,表示手動(dòng)提交事務(wù)。
2void commit() ()手動(dòng)提交事務(wù)
3void rollback()回滾(出現(xiàn)異常時(shí)候,所有已經(jīng)執(zhí)行成功的代碼需要回退到事務(wù)開始前的狀態(tài)。)
4Savepoint setSavepoint(String name)在當(dāng)前事務(wù)中創(chuàng)建一個(gè)保存點(diǎn)

1、使用事務(wù)

package com.rk.db.g_transaction;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import com.rk.db.utils.JDBCUtil;

/**
 * // 轉(zhuǎn)賬,使用事務(wù)
 * @author RK
 *
 */
public class Demo01
{
	public static void main(String[] args)
	{
		Connection conn = null;
		try
		{
			conn = JDBCUtil.getConnection();
			// 1、設(shè)置事務(wù)為手動(dòng)提交
			conn.setAutoCommit(false);

			boolean flag = true; //表示是否出現(xiàn)SQL異常
			transferMoney(conn, 100, "張三", "李四",flag);
		}
		catch (SQLException e)
		{
			System.out.println("轉(zhuǎn)賬失敗!");
			try
			{
				// 2、 出現(xiàn)異常,需要回滾事務(wù)
				conn.rollback();
				System.out.println("回滾操作成功?。。?);
			}
			catch (SQLException ex)
			{
				ex.printStackTrace();
			}
		}
		finally
		{
			// 3、所有的操作執(zhí)行成功, 提交事務(wù)
			try
			{
				conn.commit();
				System.out.println("執(zhí)行完畢!");
			}
			catch (SQLException e)
			{
				e.printStackTrace();
			}
			JDBCUtil.closeQuietly(conn);
		}
	}

	/**
	 * 模擬銀行轉(zhuǎn)賬
	 * @param conn 數(shù)據(jù)庫連接
	 * @param moneyNum 轉(zhuǎn)賬的金額
	 * @param userAdd 收到Money的用戶
	 * @param userSub 支出Money的用戶
	 * @param flag 是否模擬SQL Exception異常,true表示出現(xiàn),false表示不出現(xiàn)
	 * @throws SQLException
	 */
	private static void transferMoney(Connection conn, 
			long moneyNum, String userAdd, String userSub,
			boolean flag) throws SQLException
	{
		PreparedStatement pstmtAdd = null;
		PreparedStatement pstmtSub = null;

		try
		{
			String sqlAddMoney = "update T_Bank set money=money+? where username=?";
			pstmtAdd = conn.prepareStatement(sqlAddMoney);
			pstmtAdd.setLong(1, moneyNum);
			pstmtAdd.setString(2, userAdd);
			pstmtAdd.executeUpdate();
			
			if(flag)
			{
				throw new SQLException("模擬SQL執(zhí)行出錯(cuò)");
			}

			String sqlSubMoney = "update T_Bank set money=money-? where username=?";
			pstmtSub = conn.prepareStatement(sqlSubMoney);
			pstmtSub.setLong(1, moneyNum);
			pstmtSub.setString(2, userSub);
			pstmtSub.executeUpdate();
		}
		finally
		{
			JDBCUtil.closeQuietly(pstmtAdd);
			JDBCUtil.closeQuietly(pstmtSub);
		}

	}
}

2、使用事務(wù),回滾到指定的代碼段

package com.rk.db.g_transaction;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;

import com.rk.db.utils.JDBCUtil;

/**
 * // 轉(zhuǎn)賬,使用事務(wù), 回滾到指定的代碼段
 * @author RK
 *
 */
public class Demo02
{
	public static void main(String[] args)
	{
		Connection conn = null;
		Savepoint sp = null;
		try
		{
			conn = JDBCUtil.getConnection();
			// 1、設(shè)置事務(wù)為手動(dòng)提交
			conn.setAutoCommit(false);

			transferMoney(conn, 1000, "李四", "張三",false);
			
			// 如果失敗,回滾到這個(gè)位置
			sp = conn.setSavepoint();
			
			boolean flag = true; //表示是否出現(xiàn)SQL異常
			transferMoney(conn, 500, "張三", "李四",flag);
		}
		catch (SQLException e)
		{
			System.out.println("轉(zhuǎn)賬失敗!");
			try
			{
				// 2、 出現(xiàn)異常,需要回滾 (回滾到指定的代碼段)
				conn.rollback(sp);
				System.out.println("回滾到指定位置操作成功!??!");
			}
			catch (SQLException ex)
			{
				ex.printStackTrace();
			}
		}
		finally
		{
			// 3、所有的操作執(zhí)行成功, 提交事務(wù)
			try
			{
				conn.commit();
				System.out.println("執(zhí)行完畢!");
			}
			catch (SQLException e)
			{
				e.printStackTrace();
			}
			JDBCUtil.closeQuietly(conn);
		}
	}

	/**
	 * 模擬銀行轉(zhuǎn)賬
	 * @param conn 數(shù)據(jù)庫連接
	 * @param moneyNum 轉(zhuǎn)賬的金額
	 * @param userAdd 收到Money的用戶
	 * @param userSub 支出Money的用戶
	 * @param flag 是否模擬SQL Exception異常,true表示出現(xiàn),false表示不出現(xiàn)
	 * @throws SQLException
	 */
	private static void transferMoney(Connection conn, 
			long moneyNum, String userAdd, String userSub,
			boolean flag) throws SQLException
	{
		PreparedStatement pstmtAdd = null;
		PreparedStatement pstmtSub = null;

		try
		{
			String sqlAddMoney = "update T_Bank set money=money+? where username=?";
			pstmtAdd = conn.prepareStatement(sqlAddMoney);
			pstmtAdd.setLong(1, moneyNum);
			pstmtAdd.setString(2, userAdd);
			pstmtAdd.executeUpdate();
			
			if(flag)
			{
				throw new SQLException("模擬SQL執(zhí)行出錯(cuò)");
			}

			String sqlSubMoney = "update T_Bank set money=money-? where username=?";
			pstmtSub = conn.prepareStatement(sqlSubMoney);
			pstmtSub.setLong(1, moneyNum);
			pstmtSub.setString(2, userSub);
			pstmtSub.executeUpdate();
		}
		finally
		{
			JDBCUtil.closeQuietly(pstmtAdd);
			JDBCUtil.closeQuietly(pstmtSub);
		}

	}
}

標(biāo)題名稱:JDBC系列:(7)使用Connection操作事務(wù)
本文URL:http://muchs.cn/article18/jcjegp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、全網(wǎng)營銷推廣、用戶體驗(yàn)定制網(wǎng)站、App設(shè)計(jì)、品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作