For J2EE applications, the processing of transactions generally have two modes: 1. Transaction depends on a particular transaction resource is the most common mode in application development, that is, transaction management through the transaction mechanism provided by specific resources. For example, through JDBC, JTA's Rollback, Commit method; Hibernate Transaction's Rollback, Commit method, etc. This method is quite familiar. 2. Relying on the parametric transaction management of the container to achieve external management of the transaction through the intensive parametric transaction mechanism provided by the container, such as the transaction management mode in EJB. For example, in the following EJB transaction definition, the DOSSIONBEAN MySession is defined as a Required. That is, when the MySession.DoServer method is called by a thread, the container incorporates this thread into the transaction management container. If an exception occurs during the method call, the current transaction will be automatically rolled back by the container, and if the method is end, the container will Automatically submit the current transaction.
What can Spring transaction management give us what? The XML configuration segment shows the transaction setting mode in Spring:
Propagation_required, readonly prop> props> property> bean> beans> configuration resource definitions such as DataSource, TransactionManager. These resources are a TransactionProxyFactoryBean service called UserDaoproxy, while UserDaoproxy has a transactional package for UserDao containing actual data logic. It can be seen that in the "TransactionAttributes" attribute of UserDaoproxy, we define the transaction policy for Userdao, which is intended to start the transaction management range in INSERT (such as the UserDao.insertuser method). If you throw an exception in this method, Spring rolls the current transaction, if the method is ended normally, the transaction is submitted. For all the methods starting with GET (such as the userDao.getuser method), the read-only transaction mechanism is processed. (Set as a read-only transaction, the persistence layer can be optimized for the data operation, such as for the only transaction Hibernate, and some database connection pools and JDBC drivers are also specialized for read-only operations. In conjunction with the sensibility cognition brought about by the above, see what is different from the transaction management in the EJB, or what is the advantage. There is naturally many aspects here, but the author believes that the two most critical is: 1. Spring can incorporate any Java Class into transaction management here Userdao just a normal Java Class we have written, which contains some basic data application logic. With Spring, we can simply implement the configurable transaction. That is, we can specify a transaction management mechanism at a certain approach. With the contrast, if the transaction management function provided by the EJB container, we have to modify Userdao in accordance with EJB specification, convert it to a standard EJB. 2. Spring transaction management does not rely on specific transaction resources. The EJB container must rely on JTA to provide transaction support. Spring's transaction management supports a variety of transaction resources such as JDBC, JTA. This provides us with more choices, making our system deployment more flexible. After simple analysis of the Spring transaction management mechanism, we will combine the specific transactional application mechanisms of the persistence layer package, and discuss the transaction management in Spring. The persistence layer package JDBCSpring has a good package for JDBC, which reduces the complexity of JDBC operations to a considerable extent by providing corresponding templates and auxiliary classes. And thanks to Spring well isolated design, JDBC package library can be used out of Spring Context independently, that is, even if the system does not use Spring as a structural frame, we can also use Spring's JDBC section (Spring-Dao. JAR) to improve our code.
As a contrast, let us first let us see a traditional JDBC code: Connection conn = null; statement stmt = null; try {conn = datasource.getConnection (); stmt = con.createstatement (); stmt.executeUpdate ("Update User Set Age = 18 where id = 'erica' ");} finally {if (stmt! = null) {Try {stmt.close ();} catch (sqlexception ex) {logger.warn (" Exception In Closing JDBC Statement, EX);}}} if (conn! = null) {Try {conn.close ();} catch (sqlexception ex) {logger.warn ("Exception in closing jdbc connection", EX);}}} Similar to the above code Very common. To perform a SQL statement, we must write 22 line code, and 21 lines are not associated with application logic, and such code will be repeated in the system else (perhaps each of the required database access). So everyone start looking for some design patterns to improve such design, the application of the Template mode is one of the typical improvements. Spring's JDBC packages, a large part is to achieve a Template mode, which provides an excellent JDBC template library, with this tool, we can easily improve traditional JDBC coding. Below is the code that modified by Spring JDBC Template, which completed the same function as the above code. JDBCTemplate JDBCTemplate = New JDBCTemplate (Datasource); JDBCTemplate.Update ("Update User Set Age = 10 Where ID = Erica '); It can be seen that the two lines of code have completed the functionality of the 19-line code implementation. All redundant code is brought into JDBCTemplate through reasonable abstract collection. Without sigh, with the Template mode, we can roughly achieve such a template, but Spring designers have completed this step in advance. Org.springframework.jdbc.core.jdbcTemplate contains this template implemented code, which is carefully designed by the Spring design team, which is a model for template applications. In particular, the use of callbacks, making the entire template structure clear and efficient. It is worth reading. TIPS: In actual development, the hard-encoded SQL statement in the code can be used as a String type property of the bean, which is defined in the configuration file with the DI mechanism to implement SQL parameterization configuration.
The above example again some improvements, by performing the update operation to avoid PrepareStatement SQLInjection vulnerabilities 9: JdbcTemplate jdbcTemplate = new JdbcTemplate (dataSource); jdbcTemplate.update ( "UPDATE user SET age = WHERE id =??", New PreparedStatementSetter () {public void setvalues (preparedStatementSetter PS) throws sqlexception {ps.setint (1, 18); ps.setstring (2, "erica");}}); can be seen, the above reference is another version of the Update method, pass There are two parameters, the first SQL for creating PreparedStatement. The second parameter is the preparedStatementStter for the preparedStatement setting parameters. The method of the second parameter is more unique, and we are dynamically built a preparedStatementSetter class and implement this abstract setValues method. Then passes this class into the Update as a parameter. After the UPDATE accepts the parameters, the method of the second parameter can be invoked to complete the initialization of PreparedStatement. Spring JDBC Template has used such a Callback mechanism, which brings great flexibility and scalability. The use of the UPDATE method is demonstrated (the same operation applies to Update, Insert, Delete). Below is an example of a query. final List userList = new ArrayList (); JdbcTemplate jdbcTemplate = new JdbcTemplate (dataSource); jdbcTemplate.query ( "SELECT name, sex, address FROM user WHERE age> 18", 9 SQL Injection: SQL statements directly lead to the introduction of parameter values System vulnerability, please refer to the following papers: http://www.governmentsecurity.org/articles/sqlinjectionmodesofattackdeFenceandWhyitmatters.php
SpringFrameWork Developer's Guide Version 0.6October 8, 2004 So many open source projects Why not Open your Documents new RowCallbackHandler () {public void processRow (ResultSet rs) throws SQLException {User user = new User ();.? User.setId (rs. GetString ("name")); user.setsex (rs.getstring ("SEX")); user.setaddress (rs.getstring ("address"); userlist.add (product);}}); here incoming There are two parameters of the Query method, the first is the SELECT query statement, the second is a RowCallbackHandler instance, and we parsed each row record obtained by RowCallbackHandler and creates a USER data object. A manual OR mapping is implemented. In addition, we can also call the stored procedure through the JDBCTemplate.call method. Query, the UPDATE method has many other different parameter versions, please refer to SpringJavadoc. JDBCTemplate and JDBCTemplate operation in the above example use JDBC default autocommit mode, that is, we can not guarantee atomicity of data operation (either all of them, either all invalid), such as jdbctemplate jdbctemplate = new JDBCTemplate (Datasource) JDBCTemplate.Update ("Update User Set Age = 10 Where ID = 'Erica'"); JDBCTemplate.Update ("Update User Set Age = Age 1 WHERE ID = 'Erica'); due to AutoCommit mode, After a UPDATE operation is complete, the record "Erica" in the database has been updated. If the second operation fails, we cannot make the entire transaction back to the initial state. This example may be irrelevant, but for a financial account system, such problems will result in fatal errors. In order to achieve data operation atomicity, we need to introduce transaction logic in the program, introduce transaction mechanisms in JDBCTemplate, there are two ways in Spring: 1. Transaction Management of Code Control 2. Transaction Management of Parameterized Configuration The following two ways.
U-Code Control Services First, make the following configuration, assuming the configuration file as (Application-Context.xml):
If you need to use a container-based data source (JNDI), we can use the following configuration: Springframework developer's Guide Version 0.6OCTOBER 8, 2004 SO MANY OPEN SOURCE Projects. Why not open your documents?
TransactionTemplate encapsulates the functions of transaction management, including transaction rollbacks, and transactions submitted after successful operation. Like JDBCTemplate, it makes us no need to be in trivial TRY / CATCH / FINALLY code. The operation performed in the DoIintrance, if throwing unfailed exceptions will be automatically rolled back, if successful is executed, will be submitted automatically. Here we deliberately create some exceptions to observe whether the database operation rollback (deliberately triggered an exception by updating the ID field in the second statement): Write a simple TestCase to observe the actual effect: InputStream is = new fileInputStream (" Application-context.xml "); xmlbeanfactory factory = new xmlbeanfactory (IS); userdao userdao = (userdao) Factory.getBean (" Userdao "); UserDao.Insertuser (); I believe how much I think the code is a bit messy, Callback class Writing seems to have been contrary to daily programming habits (although the author thinks this method is more interesting, because it is smartly solved the problem that the author has encountered in the early self-developing data access template). How to further avoid these problems? Spring's container transaction management mechanism reflects its powerful energy.
u Parameterized Configuration Transaction Management Adds a transaction-context.xml to add a transaction agent (UserDaoproxy) configuration, and because the transaction is managed by the container, Userdao no longer needs TransactionManager settings, removes it:
UserDAO.insertUser corresponding code changes as follows: public void insertUser (RegisterInfo regInfo) {JdbcTemplate jt = new JdbcTemplate (executeTestSource ()); jt.update ( "insert into users (username) values ( 'xiaxin');") JT.Update ("INSERT INTO Users (ID, Username) Values (2, 'Erica');");} The test code is modified as follows: InputStream is = new fileInputStream ("Application-Context.xml"); XMLBeanFactory Factory = NEW XMLBeanFactory (IS); // Note that this must be referenced by proxy Bean "UserDaoproxy", not directly getBean ("Userdao") //, there is still a potential problem related to mandatory transformation, see Hibernate in Spring section After / / a supplementary description of the mandatory transformation. Userdao Userdao = (userDao) Factory.getBean ("UserDaoproxy"); UserDao.insertuser (); can be seen, INSERTUSER becomes very simple. Data logic is clearly visible, comparing transaction management controlled by previous code, as well as traditional JDBC operations, I believe that everyone will have some Hawran cheerful feelings. The careful reader will say that this only shifts the code to the configuration file and does not reduce too much workload. This difference may not be important. From the perspective of application maintenance, the configuration of transaction management is clearly more advantageous. What's more, in actual development, if the previous design is meticulous, the transaction characteristics of the method will generally do not change much, after the maintenance process, we only need to face the data logic in the code. Above we introduce the template operations and the transparency mechanism in Spring in JDBCTemplate. Spring as an open application development platform. It also provides good support for other components. In the persistence layer, Spring provides templates for Hibernate, IBATIS, and JDO, and these implementations have also provided strong support for our development. Below we will introduce the use of the two mainstream persistence frames of Hibernate, IBATIS in Spring. As for JDO, due to the actual development is not wide (actually thinking that JDO prospects is worrying), it will not focus on the introduction, interested readers can see the relevant chapters in Spring-Reference. SpringFrameWork Developer's Guide Version 0.6October 8, 2004 So many open source projects. Why not Open your Documents? Hibernate in SpringHibernate in open source persistence framework is undoubtedly the most vivid recent role, its author has even been invited to join the new EJB Design Work In the middle, see the wonderful advice of Hibernate design. About Hibernate, discussed in another document of the author: "Hibernate Development Guide" http://www.xiaxin.net/Hibernate_Dev_guide.rar
. The following mainly introduces the application of Hibernate in Spring, and there is not much to describe Hibernate itself. Also taking into account Spring's good support for container transactions, the author recommends to use the container management transaction in the development of Spring Framework, to obtain the best readability of data logic code. In the following introduction, the transaction management part of the code control will be subtocated, and the parameterized container transaction management application will be focused. The principle of code-level transaction management implementation is basically consistent with JDBCTemplate above, and interested readers can see related content in Spring-Reference. For the sake of concise, we still use the example above.
First, for Hibernate, we need to configure the following: hibernate-context.xml: Class = "Net.xiaxin.dao.userdao> Corresponding to the UserS table, establish the following mapping class: user.java: / *** @ hibernate.class table = "users" * / public class user {public string username; public string password; / *** @ hibernate.id * column = "id" * type = "java.lang.Integer" * generator-class = "native" * / public Integer getId () {return id; SpringFrameWork Developer's Guide Version 0.6October 8, 2004 So many Open source projects? why not open your documents?} public void setid (integer ID) {this.id = id;} / *** @ hibernate.property column = "password" length = "50" * / public string getpassword ) {return password;} public void setPassword (String password) {this.password = password;} / *** @ hibernate.property column = "username" length = "50" * / public String getUsername () {return username; } Public void setusername (String UserName) {this.username = Username;}} The above code, specify the class / table with the xDoclet; the mapping relationship of the attribute / field, we can generate the corresponding user.hbm based on the code through xdoclet audask .xml file. For details, please refer to the article "Hibernate Development Guide". Here is the generated user.hbm.xml: Below this comparison achieve the same function Hibernate native code, presumably more experience: Session sessiontry {Configuration config = new Configuration () configure (); SessionFactory sessionFactory = config.buildSessionFactory (); session = sessionFactory.openSession ();. Transaction tx = session.begintransAction (); user user = new user (); user.setname ("erica"); user.setpassword ("mypass"); session.save (user); tx.commit ();} catch (HibernateException e) {e.printStackTrace (); tx.rollback ();} finally {session.close ();} test code: InputStream is = new FileInputStream ( "Hibernate-Context.xml"); XmlBeanFactory factory = new XmlBeanFactory (is); IUserDAO userDAO = (IUserDAO) factory.getBean ( "userDAOProxy"); SpringFrameWork Developer's Guide Version 0.6October 8, 2004 So many open source projects Why not Open your Documents User user = new User ();.? user. SetUserName ("Erica"); User.SetPassword ("mypass"); UserDao.Insertuser (user); this code does not seem to be special, but there is a subtle point: iuserdao userdao = (iuserdao) Factory.getBean (" Userdaoproxy "); This is not directly transformed with UserDao. This is different from the test code above JDBCTemplate. Not completely from design considerations, here are some special, we can try to force the bean instance to enhance the bean instance with the USERDAO class, but will get a ClassCastException, and the program exception is aborted. Why do you have such problems? Is it only such a problem with using hibernate? This is not the case, if it is transformed on the UserDao based on JDBCTEMPATE, the same problem will also appear. The iUserdao interface itself is very simple (only a definition of an insertuser method), apparently not the reason for exceptions. The reason is that Spring's AOP implementation mechanism, the previous mention, the transaction management in Spring is actually implemented based on dynamic AOP mechanism, in order to implement dynamic AOP, Spring uses Java DynamicProxy by default, but Dynamic Proxy requires its agent Objects must implement an interface that defines how to prepare for proxy. For Java Class, which does not implement any interfaces, Spring is required to implement this function via CGLIB10.