1. 程式人生 > >JNDI、JTA和JMS介紹

JNDI、JTA和JMS介紹

什麼是JNDI

JNDI全面總結原理:DataSource中事先建立多個數據庫連線,儲存在資料庫連線池中。當程式訪問資料庫時,只用從連線池中取空閒狀態的資料庫連線即可,訪問結束,銷燬資源,資料庫連線重新回到連線池,這與每次去直接訪問資料庫相比,會節省大量時間和資源。
         JNDI( Java Naming and DirectoryInterface )
,是Java平臺的一個標準擴充套件,提供了一組介面、類和關於名稱空間的概念。如同其它很多Java技術一樣,JDNIprovider-based的技術,暴露了一個 API和一個服務供應介面(SPI)。這意味著任何基於名字的技術都能通過

JNDI而提供服務,只要JNDI支援這項技術。JNDI目前所支援的技術包括 LDAPCORBA Common Object ServiceCOS)名字服務、RMINDSDNSWindows登錄檔等等。很多J2EE技術,包括EJB都依靠JNDI來組織和定位實體。可以把它理解為一種將物件和名字捆綁的技術,物件工廠負責生產出物件,這些物件都和唯一的名字綁在一起,外部資源可以通過名字獲得某物件的引用。javax.naming的包包中提供Context介面,提供了兩個很好用的方法:
<1> void bind( String name , Object object )
       
將名稱繫結到物件。所有中間上下文和目標上下文(由該名稱最終原子元件以外的其他所有元件指定)都必須已經存在。
<2>Object lookup( String name )
      
檢索指定的物件。如果 name為空,則返回此上下文的一個新例項(該例項表示與此上下文相同的命名上下文,但其環境可以獨立地進行修改,而且可以併發訪問)。執行機制:
1
首先程式程式碼獲取初始化的 JNDI 環境並且呼叫 Context.lookup() 方法從 JNDI 服務提供者那裡獲一個 DataSource 物件
2
中間層 JNDI 服務提供者返回一個 DataSource 物件給當前的 Java 應用程式這個
DataSource 物件代表了中間層服務上現存的緩衝資料來源
 3
應用程式呼叫 DataSource 物件的 getConnection() 方法
4
DataSource 物件的 getConnection() 方法被呼叫時,中間層伺服器將查詢資料庫連線緩衝池中有沒有PooledConnection 介面的例項物件。這個 PooledConnection 物件將被用於與資料庫建立物理上的資料庫連線
5
如果在緩衝池中命中了一個PooledCoonection 物件那麼連線緩衝池將簡單地更新內部的緩衝連線佇列並將該PooledConnection 物件返回。如果在緩衝池內沒有找到現成的PooledConnection 物件,那麼 ConnectionPoolDataSource 介面將會被用來產生一個新的PooledConnection 物件並將它返回以便應用程式使用
6
中間層伺服器呼叫PooledConnection 物件的 getConnection() 方法以便返還一個 java.sql.Connection 物件給當前的 Java 應用程式
7
當中間層伺服器呼叫PooledConnection 物件的 getConnection() 方法時, JDBC 資料庫驅動程式將會建立一個 Connection 物件並且把它返回中間層伺服器
8
中間層伺服器將 Connection 物件返回給應用程式 Java 應用程式,可以認為這個 Connection 物件是一個普通的 JDBC Connection 物件使用它可以和資料庫建立。事實上的連線與資料庫引擎產生互動操作
9
當應用程式不需要使用 Connection 物件時,可以呼叫 Connection 介面的 close() 法。請注意這種情況下 close() 方法並沒有關閉事實上的資料庫連線,僅僅是釋放了被應用程式佔用的資料庫連線,並將它還給資料庫連線緩衝池,資料庫連線緩衝池會自動將這個資料庫連線交給請求佇列中下一個的應用程式使用。現在,資料庫的連線沒有用到連線池幾乎很少很少,每個專案組都可能有自己的資料庫連線池元件,各容器提供商也提供了各自的資料庫連線池,下面介紹一下tomcat的資料庫連線管理。
tomcat6
資料來源配置(server.xml方式和context.xml方式)server.xml下配置你必需重啟伺服器才能生效,而context.xml配置儲存後tomcat會自動載入無需重啟JNDI配配置資料來源中需注意:專案下需要引入資料庫驅動包,並且TOMCAT下也需要引入,不然會報錯的
1.context.xml
方式
Tomcat-6.0.26\conf\context.xml
檔案當新增以下的配置資訊:

<Resource name="jdbc/mysql" auth="Container"type="javax.sql.DataSource"
               maxActive="100"maxIdle="30" maxWait="60" wait_timeout="18800"timeBetweenEvictionRunsMillis="300000"minEvictableIdleTimeMillis="600000"
               username="root"password="jdzxdb" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/sxtele?comautoReconnect=true&failOverReadOnly=false"  removeAbandoned="true"removeAbandonedTimeout="60" logAbandoned="true"/>
<Resource name="jdbc/db2" auth="Container"type="javax.sql.DataSource"
               maxActive="100"maxIdle="30" maxWait="60" wait_timeout="18800"timeBetweenEvictionRunsMillis="300000"minEvictableIdleTimeMillis="600000"
              username="lcgluser" password="lcgluser"driverClassName="com.ibm.db2.jcc.DB2Driver"
              url="jdbc:db2://133.64.46.65:50000/STEDWDB"  removeAbandoned="true"removeAbandonedTimeout="60" logAbandoned="true"/>


 其中:
name
表示指定的jndi名稱
auth
表示認證方式,一般為Container
type
表示資料來源床型,使用標準的javax.sql.DataSource
maxActive
表示連線池當中最大的資料庫連線
maxIdle
表示最大的空閒連線數
maxWait
當池的資料庫連線已經被佔用的時候,最大等待時間
logAbandoned
表示被丟棄的資料庫連線是否做記錄,以便跟蹤
username
表示資料庫使用者名稱
password
表示資料庫使用者的密碼
driverClassName
表示JDBC DRIVER
url
表示資料庫URL地址注意,這裡你配置的name值要和程式中使用的是一樣的,比如按照這個例子,程式就應該是這樣的
Java
程式碼
String gENV = "java:comp/env/"; 
Context ctx = new InitialContext();   
      DataSource ds = (DataSource)ctx.lookup(gENV+"jdbc/mysql"); 
      Connection conn =ds.getConnection();
String gENV = "java:comp/env/";
Context ctx = new InitialContext();
      DataSource ds =(DataSource)ctx.lookup(gENV+"jdbc/db2");
      Connection conn =ds.getConnection();
 
關於獲取資料來源的語法,大體有(javax.sql.DataSource) ctx.lookup("java:comp/env/XXX")(javax.sql.DataSource)ctx.lookup("XXX")兩種寫法,好多人以為這兩種寫法是相同的,以為都是通過JNDI來獲取資料來源。其實java:comp/env JNDI是不同的,java:comp/env 是環境命名上下文(environmentnaming contextENC)),是在EJB規範1.1以後引入的,引入這個是為了解決原來JNDI查詢所引起的衝突問題,也是為了提高EJB或者J2EE應用的移植性。ENC是一個引用,引用是用於定位企業應用程式的外部資源的邏輯名。引用是在應用程式部署描述符檔案中定義的。在部署時,引用被繫結到目標可操作環境中資源的物理位置(JNDI名)。使用ENC是把對其它資源的JNDI查詢的硬編碼解脫出來,通過配置這個引用可以在不修改程式碼的情況下,將引用指向不同的EJB(JNDI)J2EE中的引用常用的有:

什麼是JTA

Java Transaction APIJava事務API(JTA)Java Transaction API(Application Programming Interface)什麼是JTA Transaction?它有怎樣的特點呢?JTA Transaction是指由J2EE Transaction manager去管理的事務。其最大的特點是呼叫UserTransaction介面的begin,commit和rollback方法來完成事務範圍的 界定,事務的提交和回滾。JTATransaction可以實現同一事務對應不同的資料庫,但是它仍然無法實現事務的巢狀。分散式事務的規範由OMG的OTS所描述。 
JTA
是隻是一組java介面用於描述,J2ee框架中事務管理器與應用程式,資源管理器,以及應用伺服器之間的事務通訊。 它主要包括高層介面即面向應用程式的介面;XAResource介面即面向資源的介面;以及事務管理器的介面。值得注意的是JTA只提供了介面,沒有具體的實現。 
JTS
是服務OTS的JTA的實現。簡單的說JTS實現了JTA介面,並且符合OTS的規範。 資源管理器只要其提供給事務管理器的介面符合XA介面規範,就可以被事務管理器處理。 所以,JTA可以處理任何提供符合XA介面的資源。包括:資料庫,JMS,商業物件等等  


“Java
事務 API”(JTA)啟用兩階段提交功能。當配置WebSphere Application Server 以訪問資料庫時,可選擇具有 JTA 能力的驅動程式。如果需要兩階段提交功能,則必須使用啟用 JTA 的驅動程式。 只要您在事務中呼叫了多個數據庫連線,就需要 JTA。只要您在事務中呼叫了多個數據庫伺服器,就需要兩階段提交。這些連線可以是相同的物理資料庫伺服器或多個數據庫伺服器。例如:
[list=1][*]
實體企業 BeanEntity1 在應用程式伺服器 AppServer1 中部署。[*]實體企業 Bean Entity2 在應用程式伺服器AppServer1 中部署。[*]會話企業 Bean Session1 在應用程式伺服器 AppServer1 中部署。[/list]如果Session1 對同一事務內的 Entity1 和 Entity2 呼叫了方法而這兩個企業 Bean 正在使用不同的物理資料庫連線,則必須對 Entity1 和 Entity2 使用的資料來源啟用 JTA。當從相同的資料來源物件獲取那些連線時,這也是成立的。這需要具有 JTA 能力的驅動程式以提交事務。當事務涉及到多個程序時,JTA 也是必需的。例如,一個事務可能會涉及在多個應用程式伺服器中部署的企業 Bean。
[list=1][*]
實體企業 BeanEntity1 在應用程式伺服器 AppServer1 中部署。[*]實體企業 Bean Entity2 在應用程式伺服器AppServer2 中部署。[*]會話企業 Bean Session1 在應用程式伺服器 AppServer1 中部署。[/list]如果Session1 對同一事務(此事務構成一個分散式事務)內的 Entity1 和 Entity2 呼叫了方法,則必須對 Entity1 和 Entity2 使用的資料來源啟用 JTA。效能實現JTA 啟用的連線與非 JTA 啟用的連線執行情況不同。基於此原因,如果您的應用程式不需要 JTA,則最好使用非 JTA 啟用的驅動程式。 其它資訊有關 WebSphere Application Server 如何支援 JTA 的資訊,參見 WebSphere Application Server DB2UDB iSeries版的事務處理及其子主題。

什麼是JMS

jmsJava訊息服務(JavaMessage Service應用程式介面是一個Java平臺中關於面向訊息中介軟體(MOM)的API,用於在兩個應用程式之間,或分散式系統中傳送訊息,進行非同步通訊。Java訊息服務是一個與具體平臺無關的API,絕大多數MOM提供商都對JMS提供支援。jms同時也可以指Journal of Marketing Science,《營銷科學學報》的簡稱。此外,佳木斯的拼音縮寫也是jms