0316 事务
事务,就是一件事情有n个组成单元,这些组成单元要么都成功,要么都失败,将n个组成单元放在事务中
在mysql事务中一条sql语句默认就是一个事务
如果想手动开启事务
start transaction 开启事务命令
commit提交事务,意思是从开启事务到提交事务命令之间的语句都认为是有效的语句,被更新到数据库中。
rollback回滚事务,意思是认为开启事务到回滚事务之间的语句都认为是无效的语句,都不会更新数据库中的数据。
开启事务:
更改数据
此时查询一下
显示数据已经更改,但是真正数据库中的表中的数据并没有发生变化,因为这都是在内存中进行了
当执行了commit提交事务,这时数据库中的数据会改变。
而如果执行了rollback
这时,在rollback之前所有操作数据库的语句 全部视为无效,数据库数据也不会改变
JJDBC事务操作
默认是自动事务,每执行一条sql语句都视为一个事务
通过jdbc的API手动事务
开启事务:conn.setAutoComnmit(false);
提交事务:conn.commit()
回滚事务:conn.rollback();
代码展示:
transfer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/TransferServlet" method="post"> 转出账户:<input type="text" name="out"><br> 转入账户:<input type="text" name="in"><br> 金额:<input type="text" name="money"><br> <input type="submit" value="确认"> </form> </body> </html>
TransferServlet.java
package com.oracle.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.oracle.service.AccountService; public class TransferServlet extends HttpServlet { private AccountService accountService=new AccountService(); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String out=request.getParameter("out"); String in=request.getParameter("in"); String mstr=request.getParameter("money"); double m=Double.parseDouble(mstr); int row=accountService.transfer(out, in, m); response.setContentType("text/html;charset=utf-8"); if(row>0){ response.getWriter().write("转账成功"); }else{ response.getWriter().write("转账失败"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
accountService.java
package com.oracle.service; import java.sql.Connection; import java.sql.SQLException; import com.oracle.dao.AccountDao; import com.oracle.tools.MYDBUtils; public class AccountService { private AccountDao accountDao=new AccountDao(); //转账方法 public int transfer(String out,String in,double m){ int row=0; int row2=0; //获取链接对象 Connection conn=MYDBUtils.getconn(); try { //开启实物 conn.setAutoCommit(false); row=accountDao.outmoney(conn,out, m); row2=accountDao.inmoney(conn,in, m); } catch (SQLException e) { e.printStackTrace(); //回滚 try { conn.rollback(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } }finally { //提交事务 try { conn.commit(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(row>0&&row2>0){ return 1; }else{ return 0; } } }
accountDao.java
package com.oracle.dao; import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import com.oracle.tools.MYDBUtils; public class AccountDao { //转出 public int outmoney(Connection conn,String out,double m) throws SQLException{ QueryRunner qr=new QueryRunner(); String sql="update account set money=money-? where aname=?"; int row=qr.update(conn,sql,m,out); return row; } //转入 public int inmoney(Connection conn,String in,double m) throws SQLException{ QueryRunner qr=new QueryRunner(); String sql="update account set money=money+? where aname=?"; int row=qr.update(conn,sql,m,in); return row; } }
MYDBUtils
package com.oracle.tools; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; public class MYDBUtils { public static final String DRIVER = "com.mysql.jdbc.Driver"; public static final String URL = "jdbc:mysql://localhost:3306/java1127?characterEncoding=utf-8"; public static final String USERNAME = "root"; public static final String PASSWORD = "123456"; /* * 创建连接池BasicDataSource */ public static BasicDataSource dataSource = new BasicDataSource(); //静态代码块 static { //对连接池对象 进行基本的配置 dataSource.setDriverClassName(DRIVER); // 这是要连接的数据库的驱动 dataSource.setUrl(URL); //指定要连接的数据库地址 dataSource.setUsername(USERNAME); //指定要连接数据的用户名 dataSource.setPassword(PASSWORD); //指定要连接数据的密码 } /* * 返回连接池对象 */ public static DataSource getDataSource(){ return dataSource; } //获取链接对象 public static Connection getconn(){ Connection conn=null; try { conn=dataSource.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return conn; } }
注意:控制事务的connnection必须是同一个
事务的特性和隔离级别
事务的特性ACID
(1)原子性(Atomicity)
(2)一致性(Consistency)
(3)隔离性(Isolation)
(4)持久性(Durability)