1.Connection類別中常用的方法回顧
1.1 Statement createStatement() throws SQLException;
實例建立一個Statement實例(即建立一個Statement實例(即建立一個Statement實例(即建立一個Statement實例(即建立一個Statement實例(即建立一個Statement實例(即建立一個Statement實例(即建立一個Statement實例(即建立一個Statement實例(即建立一個Statement實例》 :建立一個SQL執行物件)
1.2 PreparedStatement prepareStatement(String sql) throws SQLException;
當物件(即:建立一個預編譯執行物件) 1.3 void setAutoCommit(boolean autoCommit) throws SQLException;
設定事務的自動提交(false為關閉自動提交,true為啟動自動提交)
# 1.4AcobD1.4
# 手動提交事務 1.5 void rollback() throws SQLException;# 手動回滾交易# 手動回滾到事務
# 手動回滾交易##的經典案例:銀行轉帳案例
轉出和轉入是一個事務,如果轉出成功但是轉入失敗的會就需要進行事務回滾,否則就出出現轉出者餘額減少但是轉入者餘額沒有增加
注意:事務的提交與回滾是透過Connection提供的方法來呼叫的;本質上事務還是依賴資料庫的實作; Connection的方法實質上也是呼叫了資料庫事務機制.
2.1 不使用事務控制的轉帳業務
缺點:如果轉入成功,但是轉入失敗的話,會造成轉出者餘額減少,但是轉入者餘額不變
##
1 package cn.xiangxu.entity; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.util.Scanner; 6 7 import cn.xiangxu.tools.DBUtil; 8 9 public class Test {10 public static void main(String[] args) {11 Scanner scanner = new Scanner(System.in);12 System.out.println("请输入转出用户名:");13 String outName = scanner.nextLine();14 System.out.println("请输入需要转出的资金额度:");15 Double money = Double.parseDouble(scanner.nextLine());16 System.out.println("请输入转入用户名:");17 String inName = scanner.nextLine();18 System.out.println("转出账户为:" + outName + "转出金额为:" + money + "转入账户为:" + inName);19 20 21 Connection conn = null;22 try {23 conn = DBUtil.getConnection(); // 实例化连接对象24 25 // conn.setAutoCommit(false); // 关闭自动提交事务功能26 27 String sql = "UPDATE client "28 + "SET account = account - ? " 29 + "WHERE name = ? ";30 PreparedStatement ps = conn.prepareStatement(sql);31 ps.setDouble(1, money);32 ps.setString(2, outName);33 Integer rs = ps.executeUpdate();34 if(rs > 0) {35 System.out.println("转出成功");36 } else {37 System.out.println("转出失败");38 return; // 转出失败跳出函数,不再执行下面的语句;但是finally中的语句还是会执行的,因为就算天塌下来finally中的语句都会执行39 }40 41 System.out.println("======分割线=======");42 43 String sql_in = "UPDATE client "44 + "SET account = account + ? " 45 + "WHERE name = ? ";46 PreparedStatement ps_in = conn.prepareStatement(sql_in);47 ps_in.setDouble(1, money);48 ps_in.setString(2, inName);49 Integer judge_in = ps_in.executeUpdate();50 if(judge_in > 0) {51 System.out.println("转入成功");52 // conn.commit(); // 转出、转入都成功就提交事务53 } else {54 System.out.println("转入失败");55 // conn.rollback(); // 转出成功、转入失败就回滚事务56 }57 58 // conn.setAutoCommit(true); // 打开自动提交事务59 60 } catch (Exception e) {61 // TODO Auto-generated catch block62 e.printStackTrace();63 } finally {64 System.out.println("我是finally中的语句哟");65 try {66 DBUtil.closeConnection();67 } catch (Exception e) {68 // TODO Auto-generated catch block69 e.printStackTrace();70 }71 }72 }73 }
1 CREATE TABLE client (2 id INT (10) PRIMARY KEY,3 name VARCHAR (10),4 pwd VARCHAR (10),5 account INT (20)6 );
1 package cn.xiangxu.tools; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.sql.Connection; 6 import java.sql.SQLException; 7 import java.util.Properties; 8 9 import org.apache.commons.dbcp.BasicDataSource;10 11 public class DBUtil {12 /*13 * ThreadLocal用于线程跨方法共享数据使用14 * ThreadLocal内部有一个Map, key为需要共享数据的线程本身,value就是其需要共享的数据15 */16 private static ThreadLocal<connection> tl; // 声明一个类似于仓库的东西17 private static BasicDataSource dataSource; // 声明一个数据库连接池对象18 19 // 静态代码块,在类加载的时候执行,而且只执行一次20 static {21 tl = new ThreadLocal<connection>(); // 实例化仓库对象22 dataSource = new BasicDataSource(); // 实例数据库连接池对象23 24 Properties prop = new Properties(); // 创建一个Properties对象用(该对象可以用来加载配置文件中的属性列表)25 InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("config/mysql.properties"); // 读取配置文件信息26 try {27 prop.load(is); // 加载配置文件中的属性列表28 29 String driverClassName = prop.getProperty("driverClassName"); // 获取属性信息30 String url = prop.getProperty("url");31 String username = prop.getProperty("username");32 String password = prop.getProperty("password");33 Integer maxActive = Integer.parseInt(prop.getProperty("maxActive"));34 Integer maxWait = Integer.parseInt(prop.getProperty("maxWait"));35 36 dataSource.setDriverClassName(driverClassName); // 初始化数据库连接池(即:配置数据库连接池的先关参数)37 dataSource.setUrl(url);38 dataSource.setUsername(username);39 dataSource.setPassword(password);40 dataSource.setMaxActive(maxActive);41 dataSource.setMaxWait(maxWait);42 43 is.close(); // 关闭输入流,释放资源44 } catch (IOException e) {45 // TODO Auto-generated catch block46 e.printStackTrace();47 } 48 49 }50 51 /**52 * 创建连接对象(注意:静态方法可以直接通过类名来调用)53 * @return 连接对象54 * @throws Exception55 */56 public static Connection getConnection() throws Exception { 57 try {58 Connection conn = dataSource.getConnection(); // 创建连接对象(利用数据库连接池进行创建)59 tl.set(conn); // 将连接对象放到仓库中60 return conn; 61 } catch (Exception e) {62 // TODO Auto-generated catch block63 e.printStackTrace();64 throw e;65 }66 }67 68 /**69 * 关闭连接对象(注意:静态方法可以通过类名直接调用)70 * @throws Exception71 */72 public static void closeConnection() throws Exception {73 Connection conn = tl.get(); // 从仓库中取出连接对象74 tl.remove(); // 清空仓库75 if(conn != null) { // 判断连接对象是否释放资源76 try {77 conn.close();78 } catch (Exception e) {79 // TODO Auto-generated catch block80 e.printStackTrace();81 throw e;82 }83 }84 }85 86 }</connection></connection>
#資料庫連線池的java原始碼
1 # zhe shi zhu shi , yi ban bu yong zhong wen 2 # deng hao liang bian mei you kong ge, mo wei mei you fen hao3 # hou mian bu neng you kong ge4 driverClassName=com.mysql.jdbc.Driver5 url=jdbc:mysql://localhost:3306/test6 username=root7 password=1828388 maxActive=1009 maxWait=3000資料庫資訊檔案
1 <project> 2 <modelversion>4.0.0</modelversion> 3 <groupid>cn.xiangxu</groupid> 4 <artifactid>testJDBC</artifactid> 5 <version>0.0.1-SNAPSHOT</version> 6 <dependencies> 7 <dependency> 8 <groupid>mysql</groupid> 9 <artifactid>mysql-connector-java</artifactid>10 <version>5.1.37</version>11 </dependency>12 <dependency>13 <groupid>junit</groupid>14 <artifactid>junit</artifactid>15 <version>4.12</version>16 </dependency>17 <dependency>18 <groupid>commons-dbcp</groupid>19 <artifactid>commons-dbcp</artifactid>20 <version>1.4</version>21 </dependency>22 </dependencies>23 </project>maven依賴檔案
1 package cn.xiangxu.entity; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.SQLException; 6 import java.util.Scanner; 7 8 import cn.xiangxu.tools.DBUtil; 9 10 public class Test {11 public static void main(String[] args) {12 Scanner scanner = new Scanner(System.in);13 System.out.println("请输入转出用户名:");14 String outName = scanner.nextLine();15 System.out.println("请输入需要转出的资金额度:");16 Double money = Double.parseDouble(scanner.nextLine());17 System.out.println("请输入转入用户名:");18 String inName = scanner.nextLine();19 System.out.println("转出账户为:" + outName + "转出金额为:" + money + "转入账户为:" + inName);20 21 22 Connection conn = null;23 try {24 conn = DBUtil.getConnection(); // 实例化连接对象25 26 conn.setAutoCommit(false); // 关闭自动提交事务功能27 28 String sql = "UPDATE client "29 + "SET account = account - ? " 30 + "WHERE name = ? ";31 PreparedStatement ps = conn.prepareStatement(sql);32 ps.setDouble(1, money);33 ps.setString(2, outName);34 Integer rs = ps.executeUpdate();35 if(rs > 0) {36 System.out.println("转出成功");37 } else {38 System.out.println("转出失败");39 return; // 转出失败跳出函数,不再执行下面的语句;但是finally中的语句还是会执行的,因为就算天塌下来finally中的语句都会执行40 }41 42 System.out.println("======分割线=======");43 44 String sql_in = "UPDATE client "45 + "SET account = account + ? " 46 + "WHERE name = ? ";47 PreparedStatement ps_in = conn.prepareStatement(sql_in);48 ps_in.setDouble(1, money);49 ps_in.setString(2, inName);50 Integer judge_in = ps_in.executeUpdate();51 if(judge_in > 0) {52 System.out.println("转入成功");53 conn.commit(); // 转出、转入都成功就提交事务54 } else {55 System.out.println("转入失败");56 conn.rollback(); // 转出成功、转入失败就回滚事务57 }58 59 conn.setAutoCommit(true); // 打开自动提交事务60 61 } catch (Exception e) {62 // TODO Auto-generated catch block63 try {64 conn.rollback(); // 捕获到异常后也需要进行事务回滚65 } catch (SQLException e1) {66 // TODO Auto-generated catch block67 e1.printStackTrace();68 } 69 e.printStackTrace();70 } finally {71 System.out.println("我是finally中的语句哟");72 try {73 DBUtil.closeConnection();74 } catch (Exception e) {75 // TODO Auto-generated catch block76 e.printStackTrace();77 }78 }79 }80 }######轉帳業務的java原始碼######### 2.3 將關閉自動提交功能、手動提交功能、手動回滾功能封裝到一個類別中#########
1 package cn.xiangxu.tools; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.sql.Connection; 6 import java.sql.SQLException; 7 import java.util.Properties; 8 9 import org.apache.commons.dbcp.BasicDataSource; 10 11 public class DBUtil { 12 /* 13 * ThreadLocal用于线程跨方法共享数据使用 14 * ThreadLocal内部有一个Map, key为需要共享数据的线程本身,value就是其需要共享的数据 15 */ 16 private static ThreadLocal<connection> tl; // 声明一个类似于仓库的东西 17 private static BasicDataSource dataSource; // 声明一个数据库连接池对象 18 19 // 静态代码块,在类加载的时候执行,而且只执行一次 20 static { 21 tl = new ThreadLocal<connection>(); // 实例化仓库对象 22 dataSource = new BasicDataSource(); // 实例数据库连接池对象 23 24 Properties prop = new Properties(); // 创建一个Properties对象用(该对象可以用来加载配置文件中的属性列表) 25 InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("config/mysql.properties"); // 读取配置文件信息 26 try { 27 prop.load(is); // 加载配置文件中的属性列表 28 29 String driverClassName = prop.getProperty("driverClassName"); // 获取属性信息 30 String url = prop.getProperty("url"); 31 String username = prop.getProperty("username"); 32 String password = prop.getProperty("password"); 33 Integer maxActive = Integer.parseInt(prop.getProperty("maxActive")); 34 Integer maxWait = Integer.parseInt(prop.getProperty("maxWait")); 35 36 dataSource.setDriverClassName(driverClassName); // 初始化数据库连接池(即:配置数据库连接池的先关参数) 37 dataSource.setUrl(url); 38 dataSource.setUsername(username); 39 dataSource.setPassword(password); 40 dataSource.setMaxActive(maxActive); 41 dataSource.setMaxWait(maxWait); 42 43 is.close(); // 关闭输入流,释放资源 44 } catch (IOException e) { 45 // TODO Auto-generated catch block 46 e.printStackTrace(); 47 } 48 49 } 50 51 /** 52 * 创建连接对象(注意:静态方法可以直接通过类名来调用) 53 * @return 连接对象 54 * @throws Exception 55 */ 56 public static Connection getConnection() throws Exception { 57 try { 58 Connection conn = dataSource.getConnection(); // 创建连接对象(利用数据库连接池进行创建) 59 tl.set(conn); // 将连接对象放到仓库中 60 return conn; 61 } catch (Exception e) { 62 // TODO Auto-generated catch block 63 e.printStackTrace(); 64 throw e; 65 } 66 } 67 68 /** 69 * 关闭连接对象(注意:静态方法可以通过类名直接调用) 70 * @throws Exception 71 */ 72 public static void closeConnection() throws Exception { 73 Connection conn = tl.get(); // 从仓库中取出连接对象 74 tl.remove(); // 清空仓库 75 if(conn != null) { // 判断连接对象是否释放资源 76 try { 77 conn.close(); 78 } catch (Exception e) { 79 // TODO Auto-generated catch block 80 e.printStackTrace(); 81 throw e; 82 } 83 } 84 } 85 86 /** 87 * 在执行SQL语句前关闭JDBC的自动提交事务功能 88 * @throws SQLException 89 */ 90 public static void tansBegin() throws SQLException { 91 try { 92 tl.get().setAutoCommit(false); // 从仓库中获取连接对象并调用setAutoCommit来关闭自动提交事务功能 93 } catch(SQLException e) { 94 e.printStackTrace(); 95 throw e; 96 } 97 } 98 99 /**100 * 手动回滚功能101 * @throws SQLException102 */103 public static void transBack() throws SQLException {104 tl.get().rollback(); // 从仓库中获取连接对象并调用rollback来实现事务回滚操作105 tl.get().setAutoCommit(true); // 回滚启动事务自动提交功能106 }107 108 /**109 * 手动提交功能110 * @throws SQLException111 */112 public static void transCommit() throws SQLException {113 tl.get().commit(); // 从仓库中获取连接对象并调用commit来实现事务提交操作114 tl.get().setAutoCommit(true); // 提交后启动事务自动提交功能115 }116 117 }</connection></connection>#######DBUtil############
1 package cn.xiangxu.entity; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.SQLException; 6 import java.util.Scanner; 7 8 import cn.xiangxu.tools.DBUtil; 9 10 public class Test {11 public static void main(String[] args) {12 Scanner scanner = new Scanner(System.in);13 System.out.println("请输入转出用户名:");14 String outName = scanner.nextLine();15 System.out.println("请输入需要转出的资金额度:");16 Double money = Double.parseDouble(scanner.nextLine());17 System.out.println("请输入转入用户名:");18 String inName = scanner.nextLine();19 System.out.println("转出账户为:" + outName + "转出金额为:" + money + "转入账户为:" + inName);20 21 22 Connection conn = null;23 try {24 conn = DBUtil.getConnection(); // 实例化连接对象25 26 DBUtil.tansBegin(); // 关闭自动提交事务功能27 28 String sql = "UPDATE client "29 + "SET account = account - ? " 30 + "WHERE name = ? ";31 PreparedStatement ps = conn.prepareStatement(sql);32 ps.setDouble(1, money);33 ps.setString(2, outName);34 Integer rs = ps.executeUpdate();35 if(rs > 0) {36 System.out.println("转出成功");37 } else {38 System.out.println("转出失败");39 return; // 转出失败跳出函数,不再执行下面的语句;但是finally中的语句还是会执行的,因为就算天塌下来finally中的语句都会执行40 }41 42 System.out.println("======分割线=======");43 44 String sql_in = "UPDATE client "45 + "SET account = account + ? " 46 + "WHERE name = ? ";47 PreparedStatement ps_in = conn.prepareStatement(sql_in);48 ps_in.setDouble(1, money);49 ps_in.setString(2, inName);50 Integer judge_in = ps_in.executeUpdate();51 if(judge_in > 0) {52 System.out.println("转入成功");53 DBUtil.transCommit(); // 转出、转入都成功就提交事务54 } else {55 System.out.println("转入失败");56 DBUtil.transBack(); // 转出成功、转入失败就回滚事务57 }58 59 } catch (Exception e) {60 // TODO Auto-generated catch block61 try {62 DBUtil.transBack();// 捕获到异常后也需要进行事务回滚63 } catch (SQLException e1) {64 // TODO Auto-generated catch block65 e1.printStackTrace();66 } 67 e.printStackTrace();68 } finally {69 System.out.println("我是finally中的语句哟");70 try {71 DBUtil.closeConnection();72 } catch (Exception e) {73 // TODO Auto-generated catch block74 e.printStackTrace();75 }76 }77 }78 }######轉帳業務java原始碼######
以上是JDBC實作交易提交與回滾實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。

Java的平台獨立性是指編寫的代碼可以在任何安裝了JVM的平台上運行,無需修改。 1)Java源代碼編譯成字節碼,2)字節碼由JVM解釋執行,3)JVM提供內存管理和垃圾回收功能,確保程序在不同操作系統上運行。

Javaapplicationscanindeedencounterplatform-specificissuesdespitetheJVM'sabstraction.Reasonsinclude:1)Nativecodeandlibraries,2)Operatingsystemdifferences,3)JVMimplementationvariations,and4)Hardwaredependencies.Tomitigatethese,developersshould:1)Conduc

云计算显著提升了Java的平台独立性。1)Java代码编译为字节码,由JVM在不同操作系统上执行,确保跨平台运行。2)使用Docker和Kubernetes部署Java应用,提高可移植性和可扩展性。

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

容器化技術如Docker增強而非替代Java的平台獨立性。 1)確保跨環境的一致性,2)管理依賴性,包括特定JVM版本,3)簡化部署過程,使Java應用更具適應性和易管理性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver Mac版
視覺化網頁開發工具

SublimeText3 Linux新版
SublimeText3 Linux最新版