高级Meb技术 Java 2 Enterprise Edition
高级Web技术 Java 2 Enterprise Edition
本次课程内容 EJB事务处理 Container Managed transaction Bean Managed transaction
本次课程内容 ◼ EJB事务处理 ◼ Container Managed Transaction ◼ Bean Managed Transaction
CMT
CMT
CMT Container Managed transaction 程序员在Bean的源程序中没有事务边界控制的代码(如 事务开始、回滚、提交等) ■在部署描述符中指定事务属性,由容器控制事务的边界。 容器维护的事务是方法级的 即默认将一个方法当作一个事务执行 当方法执行的过程中,发生系统级异常,容器会自动将事 务回滚,即将方法前面执行的结果恢复。 适用于所有类型的EJB 例子背景 银行账户例子 EJB提供存款、取款、获取余额的操作
CMT ◼ Container Managed Transaction ◼ 程序员在Bean的源程序中没有事务边界控制的代码(如 事务开始、回滚、提交等) ◼ 在部署描述符中指定事务属性,由容器控制事务的边界。 ◼ 容器维护的事务是方法级的 ◼ 即默认将一个方法当作一个事务执行 ◼ 当方法执行的过程中,发生系统级异常,容器会自动将事 务回滚,即将方法前面执行的结果恢复。 ◼ 适用于所有类型的EJB ◼ 例子背景 ◼ 银行账户例子 ◼ EJB提供存款、取款、获取余额的操作
Remote接口 package bank; import javax ejb. *k import java rmi. x publicinterface Banker extends EJBobject { public void deposit(string accountName, int amount) throws Remote Exception, BankerFailure Exception; public void withdraw( String accountName, int amount) throws RemoteException BankerFailure Exception; public int getBalance( String accountName) throws RemoteException, BankerFailure Exception 定义商业方法
Remote接口 package bank; import javax.ejb.*; import java.rmi.*; public interface Banker extends EJBObject { public void deposit(String accountName, int amount) throws RemoteException, BankerFailureException; public void withdraw(String accountName, int amount) throws RemoteException, BankerFailureException; public int getBalance(String accountName) throws RemoteException, BankerFailureException; } 定义商业方法
Home接口 package bank; import java rmi Remote EXception; import javax. ejb. * i public interface BankerHome extends EJBHome public Banker create throws RemoteException, Create Exception; 定义 create方法
Home接口 package bank; import java.rmi.RemoteException; import javax.ejb.*; public interface BankerHome extends EJBHome { public Banker create() throws RemoteException, CreateException; } 定义create方法
Bean类实现(Part1) package bank; //import public class Banker Bean implements Session Bean Data Source ds, Connection conn public void ejbcreateo throws Create Exception tr InitialContext initialCtx= new Initial Contexto; ds=(Data Source)initialCtx lookup Java: comp/env/idbc/BankDB"F catch(Naming Exception exx throw new Create Exception("lookup datasource failed"); catch(Exception er throw new CreateException opera } public void ejbRemove0t 实现 ejbCreate方法 public void ejbPassivateot 查找所用的数据源 public void ejbActivate t public void setSession Context( Session Context Cont //Part 2,3 }
Bean类实现(Part 1) package bank; //import ... public class BankerBean implements SessionBean { DataSource ds; Connection conn; public void ejbCreate() throws CreateException{ try{ InitialContext initialCtx = new InitialContext(); ds = (DataSource)initialCtx.lookup("java:comp/env/jdbc/BankDB"); }catch(NamingException ex){ throw new CreateException("lookup datasource failed"); }catch(Exception e){ throw new CreateException("operation failed"); } } public void ejbRemove() {} public void ejbPassivate() {} public void ejbActivate() {} public void setSessionContext(SessionContext Context) {} //Part 2,3 } 实现ejbCreate方法: 查找所用的数据源
Bean类实现(Part2) public void deposit(String accountName, int amountthrows Banker FailureException ryt conn= ds getConnection(; Statement stmt conn create Statement Resultset res= stmt. executeQuery( SELECT* FROM accounts WheRe accountname = accountName + if(res nextOR nt new Balance new Balance= res getInt(balance)+amount; stmt. execute ("UPDATE accounts SET balance =+ newBalance) throw new BankerFailure Exception invalid accountName"); connclosed catch(EXception ek throw new Banker FailureException ("invalid accountName } 利用数据源获取一个数 据源查 询账户余 额 据库连接,完成相应的数据库操 作
Bean类实现(Part 2) public void deposit(String accountName, int amount)throws BankerFailureException{ try{ conn = ds.getConnection(); Statement stmt = conn.createStatement(); ResultSet res = stmt.executeQuery( "SELECT * FROM accounts WHERE accountname = '" + accountName + "'"); if(res.next()){ int newBalance; newBalance = res.getInt("balance") + amount; stmt.execute("UPDATE accounts SET balance = " + newBalance); } else{ throw new BankerFailureException("invalid accountName"); } conn.close(); }catch(Exception e){ throw new BankerFailureException("invalid accountName"); } } public int getBalance(String accountName) throws BankerFailureException{ //利用数据源查询账户余额... } 实现deposit、getBalance方法: 利用数据源获取一个数 据库连接,完成相应的数据库操 作
Bean类实现(Part31) public void withdraw( String accountName int amount) throws Banker Failure Exception try System. out printIn (" Entry withdraw"; conn= ds. getconnectiono Statement stmt= conn. createStatemento; Resultset res stmt execute Query( SELECT FROM accounts WHERE accountname = accountName+) //从账户上减去相应的金额 int new Balance if(res nexto if(amount res getInt( balance")) throw new BankerFailure Exception ("no enough balance "); newBalance res getInt("balance")-amount; tmt. execute ( "UPDATE accounts sET balance =" new Balance ); elset throw new Banker Failure Exception(" invalid accountName ) conn.close System. out. printIn (accountName+s balance changed to"+ new Balance); System. out println("pushing cash.. ) ∥操纵取款机为用户吐出现金 push Cash(amount) 数据库操作 System. out. printin( withdraw finished succes Scatch(sQLException er 首先利用数据源获取数 throw new Banker FailureException( "operatior据库连接,操作账户记录,从当 前账户上扣除所取金额
Bean类实现(Part 3_1) public void withdraw(String accountName, int amount) throws BankerFailureException{ try{ System.out.println("Entry withdraw"); conn = ds.getConnection(); Statement stmt = conn.createStatement(); ResultSet res = stmt.executeQuery( "SELECT * FROM accounts WHERE accountname = '" + accountName + "'"); //从账户上减去相应的金额 int newBalance; if(res.next()){ if(amount > res.getInt("balance")){ throw new BankerFailureException("no enough balance"); } newBalance = res.getInt("balance") - amount; stmt.execute("UPDATE accounts SET balance = " + newBalance); } else{ throw new BankerFailureException("invalid accountName"); } conn.close(); System.out.println(accountName + "'s balance changed to " + newBalance); System.out.println("pushing cash..."); //操纵取款机为用户吐出现金 pushCash(amount); System.out.println("withdraw finished successfully"); }catch(SQLException e){ throw new BankerFailureException("operation failed"); } } 数据库操作: 首先利用数据源获取数 据库连接,操作账户记录,从当 前账户上扣除所取金额
Bean类实现(Part31) public void withdraw( String accountName int amount)throws Banker Failure Exception try System. out println(" Entry withdraw"); conn= ds getConnection(; Statement stmt conn createStatemento Resultset res= stmt. executeQuery( SELECT FROM accounts where accounti ∥)从账户上减去相应的金额 int new balance if(res nextoR 机械操作 if(amount>res getInt("balance") 操纵取款机为用户吐出 throw new BankerFa 现金。因为该操作涉及机械操作, mtem"a可能由于机械故障等原因而操作 newBal ATE acconts失败。 els throw new Banker Faily/eXception conn doseo; System. out. println(accountNan balance changed to+ newBalance) System. out println("pushing cash. ) //操纵取款机为用户吐出现金 push Cash(amount); System. out. printIn("withdraw finished successfully") Scatch(sQLEXception e throw new BankerFailureException(operation failed")
Bean类实现(Part 3_1) public void withdraw(String accountName, int amount) throws BankerFailureException{ try{ System.out.println("Entry withdraw"); conn = ds.getConnection(); Statement stmt = conn.createStatement(); ResultSet res = stmt.executeQuery( "SELECT * FROM accounts WHERE accountname = '" + accountName + "'"); //从账户上减去相应的金额 int newBalance; if(res.next()){ if(amount > res.getInt("balance")){ throw new BankerFailureException("no enough balance"); } newBalance = res.getInt("balance") - amount; stmt.execute("UPDATE accounts SET balance = " + newBalance); } else{ throw new BankerFailureException("invalid accountName"); } conn.close(); System.out.println(accountName + "'s balance changed to " + newBalance); System.out.println("pushing cash..."); //操纵取款机为用户吐出现金 pushCash(amount); System.out.println("withdraw finished successfully"); }catch(SQLException e){ throw new BankerFailureException("operation failed"); } } 机械操作: 操纵取款机为用户吐出 现金。因为该操作涉及机械操作, 可能由于机械故障等原因而操作 失败