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)

posted @ 2021-03-16 15:36  公雪  阅读(97)  评论(0编辑  收藏  举报