Abandon the framework and implement JDBC transaction control in a layered architecture

Source: Internet
Author: User

Many projects, especially web projects, basically use frameworks such as struts1, struts2., spring, hibernate, springmvc, and ibatise to improve development efficiency. In terms of transaction processing, spring is particularly prominent. It encapsulates transactions well. With the configuration of AOP, You can flexibly configure the transaction on any layer. However, in many cases, it is necessary to directly use JDBC for transaction control based on requirements and application considerations.

The transaction should be based on the business logic. A complete business should correspond to a method in the business layer, instead of multiple methods. If the business execution process encounters exceptions, the entire transaction should be rolled back. Therefore, the transaction control should be placed in the business layer. However, the design of the persistence layer should follow a very important principle: the persistence layer should ensure the atomicity of the operation, that is to say, each method in the persistent layer should be inseparable, that is to say, the connection of the database should be the same connection from beginning to end, instead of restarting a new database connection after a DaO operation is completed and the database connection is closed!

The above statement may be a bit abstract. For example, if you want to delete a class for clazze and student operations, you need to delete all the students in the class before deleting the class. These two operations should be put in the same transaction, either deleting the students and the class at the same time succeeds or failing at the same time, the student data cannot be deleted, but the class data cannot be deleted. This is what we mentioned above-atomicity.

Maybe the above description is a little abstract. It doesn't matter. We use code to speak.

First, define two Dao interfaces, one is the class interface (clazzedao) and the other is the student interface (studentdao), which only provides the deletion function.

Clazzedao:

/*** Filename: clazzedao. java * creationtime: 2011-8-14 * Author: YJD * Email: 908599713@qq.com * site: http://hi.csdn.net/tjcyjd */package COM. tjcyjd. dao;/*** class interface ** @ author YJD */public interface clazzedao {/** Delete the corresponding class according to the ID */Public void deleteclazzebyclazzeid (INT clazzeid) throws daoexception ;}

Studentdao:

/*** Filename: studentdao. java * creationtime: 2011-8-14 * Author: YJD * Email: 908599713@qq.com * site: http://hi.csdn.net/tjcyjd */package COM. tjcyjd. dao; /*** student interface ** @ author YJD */public interface studentdao {/** delete all students in the class based on the class ID */Public void deletestudentbyclazzeid (INT clazzeid) throws daoexception ;}

After defining these two Dao interfaces, you should call these two methods in the method of deleting the class in the corresponding service layer (clazzeservice. In this way, they are placed in the same transaction. Before calling, we have to do something to get a database connection factory class (connectionfactory) and a transaction manager class (transactionmanager ).

Connectionfactory:

/*** Filename: connectionfactory. java * creationtime: 2011-8-14 * Author: YJD * Email: 908599713@qq.com * site: http://hi.csdn.net/tjcyjd */package COM. tjcyjd. commom; import Java. io. ioexception; import Java. SQL. connection; import Java. SQL. sqlexception; import Java. util. properties; import javax. SQL. datasource; import COM. mchange. v2.c3p0. datasources;/*** database connection factory ** @ author YJD */public class connectionfactory {Private Static Properties prop = new properties (); // data source Private Static datasource DS = NULL; // variable Private Static threadlocal <connection> TL = new threadlocal <connection> (); static {try {prop. load (thread. currentthread (). getcontextclassloader (). getresourceasstream ("JDBC. properties ");} catch (ioexception e) {e. printstacktrace (); system. out. println ("JDBC not found under classpath. properties file ");} // The c3p0 connection try {class is used here. forname ("com. mySQL. JDBC. driver "); datasource unpooled = CES. unpooleddatasource (prop. getproperty ("url"), Prop. getproperty ("user"), Prop. getproperty ("password"); DS = datasources. pooleddatasource (unpooled);} catch (classnotfoundexception e) {e. printstacktrace ();} catch (sqlexception e) {e. printstacktrace () ;}}/*** get the connection object of the database ** @ return */public static synchronized connection getconnection () {connection conn = TL. get (); // The current thread retrieves the connection instance if (null = conn) {try {conn = Ds. getconnection (); // retrieves a connection instance TL from the connection pool. set (conn); // bind it to the current thread} catch (sqlexception e) {e. printstacktrace () ;}} return conn;} public static synchronized transactionmanager gettranmanager () {return New transactionmanager (getconnection ());}}

Transactionmanager:

/*** Filename: transactionmanager. java * creationtime: 2011-8-14 * Author: YJD * Email: 908599713@qq.com * site: http://hi.csdn.net/tjcyjd */package COM. tjcyjd. commom; import Java. SQL. connection; import Java. SQL. sqlexception; import COM. tjcyjd. dao. daoexception;/*** Transaction Manager class ** @ author YJD */public class transactionmanager {private connection conn; protected transactionmanager (connection conn) {This. CO Nn = conn;}/*** enable transaction ** @ throws daoexception */Public void begintransaction () throws daoexception {try {If (null! = Conn &&! Conn. isclosed () {Conn. setautocommit (false); // change the transaction commit method to manual commit} catch (sqlexception e) {Throw new daoexception ("exception occurred during account opening transaction", e );}} /*** submit the transaction and close the connection ** @ throws daoexception */Public void commitandclose () throws daoexception {try {Conn. commit (); // submit the transaction system. out. println ("Commit transaction");} catch (sqlexception e) {Throw new daoexception ("exception occurred when transaction is started", e);} finally {close (conn );}} /*** roll back and close the connection ** @ throws daoexcept Ion */Public void rollbackandclose () throws daoexception {try {Conn. rollback (); system. out. println ("rollback transaction");} catch (sqlexception e) {Throw new daoexception ("exception occurred during transaction rollback", e );} finally {close (conn) ;}}/*** close connection ** @ Param conn * @ throws daoexception */private void close (connection conn) throws daoexception {If (Conn! = NULL) {try {conn. Close ();} catch (sqlexception e) {Throw new daoexception ("an exception occurred when closing the connection", e );}}}}

Now, we can start our business (clazzeservice ).

Clazzeservice:

/*** Filename: clazzeservice. java * creationtime: 2011-8-14 * Author: YJD * Email: 908599713@qq.com * site: http://hi.csdn.net/tjcyjd */package COM. tjcyjd. service; import COM. tjcyjd. commom. connectionfactory; import COM. tjcyjd. commom. transactionmanager; import COM. tjcyjd. dao. clazzedao; import COM. tjcyjd. dao. daoexception; import COM. tjcyjd. dao. daofactory; import COM. tjcyjd. dao. studentdao;/*** class operation class ** @ author YJD */public class clazzeservice {private clazzedao = daofactory. getinstance ("clazzedao", clazzedao. class); Private studentdao = daofactory. getinstance ("studentdao", studentdao. class);/*** Delete the class with the specified ID ** @ Param clazzeid */Public void deleteclazze (INT clazzeid) {transactionmanager Tx = connectionfactory. gettranmanager (); try {Tx. begintransaction (); // Delete studentdao for all students in the specified class. deletestudentbyclazzeid (clazzeid); // delete a specified class clazzedao. deleteclazzebyclazzeid (clazzeid); // submit the transaction and close the Tx connection. commitandclose ();} catch (daoexception e) {e. printstacktrace (); // exception rollback Tx. rollbackandclose ();}}}

We didn't write their implementation classes for the two Dao we defined above. To better understand them, I 'd like to paste them (clazzedaoimpl, studentdaoimpl) out.

Clazzedaoimpl:

/*** Filename: clazzedaoimpl. java * creationtime: 2011-8-14 * Author: YJD * Email: 908599713@qq.com * site: http://hi.csdn.net/tjcyjd */package COM. tjcyjd. dao. impl; import Java. SQL. connection; import Java. SQL. sqlexception; import Org. apache. commons. dbutils. queryrunner; import COM. tjcyjd. commom. connectionfactory; import COM. tjcyjd. dao. clazzedao; import COM. tjcyjd. dao. daoexception;/*** class interface implementation class ** @ autho R YJD */public class clazzedaoimpl implements clazzedao {private queryrunner QR = new queryrunner ();/** delete a specified class */Public void deleteclazzebyclazzeid (INT clazzeid) throws daoexception {connection conn = connectionfactory. getconnection (); // The SQL statement is mistakenly written. An additional number * is added *. String SQL = "delete * From clazze where clazze_id =? "; Try {QR. update (Conn, SQL, clazzeid); system. out. println ("deletestudentbyclazzeid method successfully executed, but no transaction is submitted");} catch (sqlexception e) {Throw new daoexception ("an exception occurred when deleting the department with the specified ID ", e );}}}

Studentdaoimpl:

/*** Filename: studentdaoimpl. java * creationtime: 2011-8-14 * Author: YJD * Email: 908599713@qq.com * site: http://hi.csdn.net/tjcyjd */package COM. tjcyjd. dao. impl; import Java. SQL. connection; import Java. SQL. sqlexception; import Org. apache. commons. dbutils. queryrunner; import COM. tjcyjd. commom. connectionfactory; import COM. tjcyjd. dao. daoexception; import COM. tjcyjd. dao. studentdao;/*** student interface implementation class ** @ aut Hor YJD */public class studentdaoimpl implements studentdao {private queryrunner QR = new queryrunner ();/** delete all students in the specified class */Public void deletestudentbyclazzeid (INT clazzeid) throws daoexception {connection conn = connectionfactory. getconnection (); string SQL = "delete from student where clazze_id =? "; Try {QR. update (Conn, SQL, clazzeid); system. out. println ("deletestudentbyclazzeid method successfully executed, but no transaction is submitted");} catch (sqlexception e) {Throw new daoexception ("an exception occurred when deleting the department with the specified ID ", e );}}}

Finally, we write a test class (clazzeservicetest) to test the code.

Clazzeservicetest:

/*** Filename: clazzeservicetest. java * creationtime: 2011-8-14 * Author: YJD * Email: 908599713@qq.com * site: http://hi.csdn.net/tjcyjd */package COM. tjcyjd. service; /*** clazzeservice test class ** @ author YJD */public class clazzeservicetest {/*** main method ** @ Param ARGs */public static void main (string [] ARGs) {testdeletedept (2);}/*** delete a specified class */public static void testdeletedept (INT clazzeid) {clazzeservice Sf = new clazzeservice (); SF. deleteclazze (clazzeid );}}

The overall project structure is as follows:

At this point, I believe everyone should be able to understand what I mean. If you still don't understand it, it doesn't matter, leave the email address with the source code ..................................................................

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.