ตัวเลือกการรวมการเชื่อมต่อกับ JDBC: DBCP กับ C3P0


312

ไลบรารีการเชื่อมต่อพูลที่ดีที่สุดสำหรับ Java / JDBC คืออะไร

ฉันกำลังพิจารณาผู้สมัครหลัก 2 คน (ฟรี / โอเพ่นซอร์ส):

ฉันได้อ่านเกี่ยวกับพวกเขามากมายในบล็อกและฟอรัมอื่น ๆ แต่ไม่สามารถตัดสินใจได้

มีทางเลือกที่เกี่ยวข้องกับสองสิ่งนี้หรือไม่?

คำตอบ:


181

DBCP ล้าสมัยและไม่ใช่เกรดการผลิต ย้อนเวลากลับไปเราได้ทำการวิเคราะห์ในบ้านทั้งสองสร้างการติดตั้งการทดสอบซึ่งสร้างภาระและการทำงานพร้อมกันกับทั้งสองเพื่อประเมินความเหมาะสมของพวกเขาภายใต้เงื่อนไขในชีวิตจริง

DBCP สร้างข้อยกเว้นอย่างต่อเนื่องในแอปพลิเคชันทดสอบของเราและพยายามที่จะบรรลุระดับประสิทธิภาพซึ่ง C3P0 นั้นมีความสามารถในการจัดการโดยไม่มีข้อยกเว้นใด ๆ

C3P0 ยังจัดการการเชื่อมต่อฐานข้อมูลอย่างแน่นหนาและการเชื่อมต่อแบบโปร่งใสอีกครั้งเมื่อดำเนินการต่อในขณะที่ DBCP ไม่เคยกู้คืนการเชื่อมต่อหากลิงก์ถูกนำออกจากด้านล่าง DBCP ยังส่งคืนออบเจ็กต์การเชื่อมต่อไปยังแอปพลิเคชันที่การส่งข้อมูลพื้นฐานเสียหาย

ตั้งแต่นั้นมาเราได้ใช้ C3P0 ในเว็บแอพหลักสำหรับผู้บริโภคที่ใช้งานหนักจำนวน 4 รายและไม่เคยมองย้อนกลับไป

UPDATE:ปรากฎว่าหลังจากหลายปีของการนั่งบนหิ้งชาว Apache คอมมอนส์ได้นำDBCP ออกจากการพักตัวและตอนนี้ก็เป็นโครงการที่พัฒนาขึ้นมาอีกครั้ง ดังนั้นโพสต์ดั้งเดิมของฉันอาจล้าสมัย

ที่ถูกกล่าวว่าฉันยังไม่ได้สัมผัสกับประสิทธิภาพการทำงานของห้องสมุดอัพเกรดใหม่นี้และไม่ได้ยินว่ามันเป็น de-พฤตินัยในกรอบงานแอพล่าสุดใด ๆ


2
ขอบคุณ! Proxool เป็นทางเลือกที่แนะนำอย่างไร? เวอร์ชั่นปัจจุบันของ Hibernate มาพร้อมกับ c3p0 และ Proxool
Dema

เราไม่ได้ลอง Proxool แต่ฉันจะลองดูสิ :)
j pimmel

5
c3p0 มีข้อบกพร่องบางประการ บางครั้งมันล้มเหลวในการจัดการจุดเชื่อมต่อ
Janning

3
ทุกอย่างเปลี่ยนไปมากตั้งแต่ 4 ปีเมื่อคุณโพสต์คำตอบนี้เป็นครั้งแรกคุณสามารถเพิ่มการอัปเดตที่แชร์สถานการณ์ปัจจุบันได้หรือไม่
Rajat Gupta

13
ฉันขอแนะนำHikariCPแต่แล้วฉันก็ช่วยเขียนมัน
brettw

177

ฉันขอเชิญคุณลองใช้BoneCP - ฟรีโอเพนซอร์สและเร็วกว่าตัวเลือกอื่น ๆ ที่มีให้ (ดูหัวข้อมาตรฐาน)

คำเตือน: ฉันเป็นผู้เขียนดังนั้นคุณสามารถพูดได้ว่าฉันลำเอียง :-)

การปรับปรุง: ณ เดือนมีนาคม 2010 ยังคงเร็วกว่าประมาณ 35% กว่าสระใหม่ Apache DBCP ("tomcat jdbc") ดูลิงค์มาตรฐานแบบไดนามิกในส่วนมาตรฐาน

อัปเดต # 2: (ธ.ค. 13) หลังจาก 4 ปีที่ผ่านมาตอนนี้มีคู่แข่งที่เร็วกว่ามากขึ้น: https://github.com/brettwooldridge/HikariCP

ปรับปรุง # 3: (กันยายน '14) โปรดพิจารณา BoneCP ที่จะเลิกใช้ณ จุดนี้ขอแนะนำให้เปลี่ยนไปใช้HikariCP

อัปเดต # 4: (เมษายน '15) - ฉันไม่ได้เป็นเจ้าของโดเมน jolbox.com อีกต่อไป


1
ชอบที่จะได้รับการแก้ไขปัญหาโดยใช้ BoneCP เป็นแหล่งข้อมูล Tomcat ปัญหาหลักที่ฉันมีกับสิ่งนี้คือมันจำเป็นต้องใช้คลาส BoneCP ใน lib Dir ของ Tomcat รวมถึงคลาส log4j และ google การทำเช่นนี้ทำให้การทำงานที่สระว่ายน้ำการเชื่อมต่อ - (มันไม่ได้ทำงานในขณะ WAR) - แต่มันขัดแย้งกับการตั้งค่าของ log4j Tomcat และป้องกันไม่ให้การส่งออกบันทึกใด ๆ จากโปรแกรมซึ่งเป็น dealbreaker แล้ว ...
เจ pimmel

1
ดูเหมือนว่าปัญหา log4j มากกว่าสิ่งอื่นใด วางสายไว้ที่ forum.jolbox.com และฉันจะช่วยคุณติดตาม ASAP
2010

3
1up, BoneCP ยอดเยี่ยม เปลี่ยนจาก C3P0 มันทำให้ฉันสามารถลบการพึ่งพาของฉันใน log4jdbc-remix เพราะมันช่วยให้คำสั่งออกจากกล่อง!
subes

68
+1 สำหรับการอัปเดตเกี่ยวกับสิ่งที่คุณไม่ได้เขียนเร็วขึ้น!
CorayThan

1
@AndrewScottEvans น่าจะดีที่สุดที่จะเปลี่ยนกลับเป็น v0.7.1
wwadge

16

ฉันมีปัญหากับ DBCP เมื่อการเชื่อมต่อหมดเวลาดังนั้นฉันจึงทดสอบ c3p0 ฉันจะปล่อยสิ่งนี้ให้กับการผลิต แต่จากนั้นเริ่มการทดสอบประสิทธิภาพ ฉันพบว่า c3p0 ทำงานได้ดีมาก ฉันไม่สามารถกำหนดค่าให้ทำงานได้ดีเลย ฉันพบว่าช้ากว่า DBCP สองเท่า

ฉันลองใช้การเชื่อมต่อ Tomcatแล้ว

นี่เร็วเป็นสองเท่าของ c3p0 และแก้ไขปัญหาอื่น ๆ ที่ฉันมีกับ DBCP ฉันใช้เวลามากมายในการตรวจสอบและทดสอบพูลทั้ง 3 คำแนะนำของฉันหากคุณกำลังปรับใช้กับ Tomcat คือการใช้ Tomcat JDBC pool ใหม่


14

สำหรับปัญหาการเชื่อมต่ออัตโนมัติกับ DBCP อีกครั้งลองใช้พารามิเตอร์การกำหนดค่า 2 รายการต่อไปนี้หรือไม่

validationQuery="Some Query"

testOnBorrow=true

ในฐานะที่เป็นเอกสาร , testOnBorrowมีค่าเริ่มต้นtrueดังนั้นหากvalidationQueryมีการกำหนด DBCP จะทดสอบการเชื่อมต่อทุกก่อนที่มันจะถูกส่งผ่านไปยังโปรแกรมประยุกต์
dma_k


12

ใช้งาน DBCP มาสองสามปีแล้วในการผลิต มันมีเสถียรภาพบูตเซิร์ฟเวอร์ DB รอด เพียงกำหนดค่าอย่างถูกต้อง มันต้องใช้พารามิเตอร์จำนวนหนึ่งเท่านั้นที่จะระบุดังนั้นอย่าขี้เกียจ นี่คือตัวอย่างข้อมูลจากรหัสการผลิตระบบของเราซึ่งแสดงรายการพารามิเตอร์ที่เราตั้งค่าไว้อย่างชัดเจนเพื่อให้ทำงานได้:

DriverAdapterCPDS driverAdapterCPDS = new DriverAdapterCPDS();
driverAdapterCPDS.setUrl(dataSourceProperties.getProperty("url"));
driverAdapterCPDS.setUser(dataSourceProperties.getProperty("username"));
driverAdapterCPDS.setPassword(dataSourceProperties.getProperty("password"));
driverAdapterCPDS.setDriver(dataSourceProperties.getProperty("driverClass"));

driverAdapterCPDS.setMaxActive(Integer.valueOf(dataSourceProperties.getProperty("maxActive")));
driverAdapterCPDS.setMaxIdle(Integer.valueOf(dataSourceProperties.getProperty("maxIdle")));
driverAdapterCPDS.setPoolPreparedStatements(Boolean.valueOf(dataSourceProperties.getProperty("poolPreparedStatements")));

SharedPoolDataSource poolDataSource = new SharedPoolDataSource();
poolDataSource.setConnectionPoolDataSource(driverAdapterCPDS);
poolDataSource.setMaxWait(Integer.valueOf(dataSourceProperties.getProperty("maxWait")));
poolDataSource.setDefaultTransactionIsolation(Integer.valueOf(dataSourceProperties.getProperty("defaultTransactionIsolation")));
poolDataSource.setDefaultReadOnly(Boolean.valueOf(dataSourceProperties.getProperty("defaultReadOnly")));
poolDataSource.setTestOnBorrow(Boolean.valueOf(dataSourceProperties.getProperty("testOnBorrow")));
poolDataSource.setValidationQuery("SELECT 0");

8

นี่คือบางบทความที่แสดงว่า DBCP มีประสิทธิภาพสูงกว่า C3P0 หรือ Proxool อย่างมาก ในประสบการณ์ของฉันเอง c3p0 ก็มีคุณสมบัติที่ดีเช่นการจัดทำงบรวมและสามารถกำหนดค่าได้มากกว่า DBCP แต่ DBCP นั้นเร็วกว่าในทุกสภาพแวดล้อมที่ฉันเคยใช้

ความแตกต่างระหว่าง dbcp และ c3p0? ไม่มีอะไรจริงๆ! (บล็อกนักพัฒนาของ Sakai) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

ดูเพิ่มเติมที่ชอบในบทความ JavaTech "Connection Pool Showdown" ในความคิดเห็นในโพสต์บล็อก


4
เร็วขึ้นในสภาพแวดล้อมแบบเธรดเดียวอาจจะบั๊กกี้และไม่เสถียรและแตกหักได้ง่ายที่อื่น

7

อีกหนึ่งทางเลือก, Proxool เป็นที่กล่าวถึงในบทความนี้

คุณอาจสามารถค้นหาสาเหตุที่ทำให้ Hibernate บันเดิล c3p0 สำหรับการนำพูลการเชื่อมต่อเริ่มต้นไปใช้


7

น่าเสียดายที่พวกเขาล้าสมัย เมื่อไม่นานมานี้ DBCP ได้รับการอัปเดตแล้วส่วนอีกสองรายการมีอายุ 2-3 ปีพร้อมข้อบกพร่องมากมาย


นั่นเป็นความจริง - รุ่นล่าสุดของ C3PO (a 0.9 รุ่นก่อนวางจำหน่าย) คือตั้งแต่เดือนพฤษภาคม 2550 รุ่นล่าสุดของ Proxool (รุ่น 0.9 รุ่นก่อนหน้า) มาจากเดือนสิงหาคม 2551 รุ่นล่าสุดของ DBCP นั้นมาจากเดือนเมษายน 2550 เช่นกัน อย่างน้อยก็เป็นรุ่น 1.2 ที่เสถียร มีอะไรดูแลอยู่ที่นั่นจริงเหรอ?
Guss

4
เพื่อความเป็นธรรมโครงการเหล่านี้ไม่ใช่โครงการขนาดใหญ่ดังนั้นคุณควรคาดหวังการอัพเดทน้อยลงและน้อยลงใน C3P0 / DBCP และเวลาผ่านไป
wwadge

7

Dbcp พร้อมใช้งานแล้วหากกำหนดค่าอย่างเหมาะสม

มันเป็นตัวอย่างที่ใช้ในเว็บไซต์การค้าของผู้เข้าชม 350000 คนต่อวันและมีกลุ่มการเชื่อมต่อ 200 คน

มันจัดการการหมดเวลาได้เป็นอย่างดีหากคุณกำหนดค่าไว้อย่างถูกต้อง

เวอร์ชัน 2 อยู่ในระหว่างดำเนินการและมีพื้นหลังซึ่งทำให้เชื่อถือได้เนื่องจากปัญหาการผลิตจำนวนมากได้รับการแก้ไขแล้ว

เราใช้มันสำหรับโซลูชันเซิร์ฟเวอร์แบตช์ของเราและมันทำงานหลายร้อยแบทช์ซึ่งทำงานกับหลายล้านบรรทัดในฐานข้อมูล

การทดสอบประสิทธิภาพดำเนินการโดย tomcat jdbc pool แสดงว่ามีประสิทธิภาพดีกว่า cp30


UBIK LOAD PACK - เราใช้ DBCP 1.4 และทำงานเป็นชุดเดียวของเราที่มีการบันทึก 10,000 รายการ เรากำลังใช้ Spring Batch + JSR 352 และคิดว่าจะเปลี่ยนเป็น HikariCP เมื่อคุณพูดว่าแบทช์ 100 รายการทำงานราบรื่นคุณหมายถึงการรันด้วย DBCP 2.x หรือเวอร์ชันอื่น ๆ หรือไม่? นอกจากนี้คุณจะแบ่งปันการกำหนดค่าด้วยหรือไม่ การกำหนดค่าของเราคือ maxActive = 150, minIdle = 15, maxIdle = 75, initialSize = 15 แต่ยังไม่เห็นแฮงค์หายไป เราไม่ได้ใช้การตรวจสอบความถูกต้องแบบสอบถามหรือ testOnBorrow / testOnReturn คุณแนะนำให้ใช้หรือไม่
Yogendra

4

เพิ่งเสียวันกับ DBCP ไปครึ่งวันแล้ว แม้ว่าฉันใช้ปล่อย DBCP ล่าสุดฉันวิ่งเข้าไปตรงปัญหาเช่นเดียวกับเจ pimmelได้ ฉันจะไม่แนะนำ DBCP เลยโดยเฉพาะอย่างยิ่งความสามารถในการโยนการเชื่อมต่อออกจากพูลเมื่อฐานข้อมูลหายไปความสามารถในการเชื่อมต่ออีกครั้งเมื่อฐานข้อมูลกลับมาและไม่สามารถเพิ่มวัตถุเชื่อมต่อกลับเข้าไปในกลุ่มได้ อ่านโพสต์ซ็อกเก็ต JDBCconnect I / O)

ฉันเปลี่ยนไปใช้ C3P0 ทันที ฉันเคยใช้มันในโปรเจ็กต์ก่อนหน้าและมันใช้งานได้และแสดงได้อย่างมีเสน่ห์


4

c3p0 นั้นดีเมื่อเราใช้ mutithreading project ในโครงการของเราเราใช้การประมวลผลหลายเธรดพร้อมกันโดยใช้ DBCP จากนั้นเราได้รับการหมดเวลาเชื่อมต่อหากเราใช้การประมวลผลเธรดมากขึ้น ดังนั้นเราจึงไปกับการกำหนดค่า c3p0


3

ทางเลือกที่ดีซึ่งเป็นเรื่องง่ายที่จะใช้เป็นDBPool

"ยูทิลิตีการรวมการเชื่อมต่อฐานข้อมูลบนจาวาสนับสนุนการหมดอายุตามเวลาการแคชคำสั่งการตรวจสอบการเชื่อมต่อและการกำหนดค่าง่าย ๆ โดยใช้ตัวจัดการพูล"

http://www.snaq.net/java/DBPool/


ฉันเปรียบเทียบ DBPool กับ BoneCP DBPool ทำให้ getConnection () ซิงโครไนซ์ท่ามกลางสิ่งอื่น ๆ และช้ากว่า BoneCP มาก (ดู: jolbox.com/forum/viewtopic.php?f=3&t=175 )
wwadge

3

เราเจอสถานการณ์ที่เราจำเป็นต้องแนะนำพูลการเชื่อมต่อและเรามีตัวเลือก 4 ตัวต่อหน้าเรา

  • DBCP2
  • C3P0
  • Tomcat JDBC
  • HikariCP

เราทำการทดสอบและเปรียบเทียบตามเกณฑ์ของเราและตัดสินใจที่จะเข้าร่วม HikariCP อ่านบทความนี้ซึ่งอธิบายว่าทำไมเราจึงเลือก HikariCP


1

หากต้องการใช้งาน C3P0 อย่างดีที่สุดให้ตรวจสอบคำตอบนี้

C3P0 :

สำหรับแอปพลิเคชันองค์กร C3P0 เป็นวิธีการที่ดีที่สุด C3P0 เป็นไลบรารีที่ใช้งานง่ายสำหรับการเพิ่มไดร์เวอร์ JDBC แบบดั้งเดิม (อิงตาม DriverManager) กับ JNDI-bindable DataSources รวมถึง DataSources ที่ใช้การเชื่อมต่อและ Statement Pooling ตามที่อธิบายโดยข้อมูลจำเพาะ jdbc3 และส่วนขยาย jdbc2 std C3P0 ยังจัดการการเชื่อมต่อฐานข้อมูลอย่างแน่นหนาและการเชื่อมต่อแบบโปร่งใสอีกครั้งเมื่อดำเนินการต่อในขณะที่ DBCP ไม่เคยกู้คืนการเชื่อมต่อหากลิงก์ถูกนำออกจากด้านล่าง

ดังนั้นนี่คือเหตุผลที่ c3p0 และกลุ่มการเชื่อมต่ออื่น ๆ ได้เตรียมคำสั่งแคชไว้ด้วยซึ่งจะช่วยให้รหัสแอปพลิเคชันหลีกเลี่ยงการจัดการทั้งหมดนี้ โดยปกติแล้วงบจะถูกเก็บไว้ในกลุ่ม LRU ที่ จำกัด ดังนั้นงบทั่วไปจึงนำมาใช้ซ้ำกับอินสแตนซ์ PreparedStatement

DBCP ยังส่งคืนออบเจ็กต์การเชื่อมต่อไปยังแอปพลิเคชันที่การส่งข้อมูลพื้นฐานเสียหาย กรณีการใช้งานทั่วไปสำหรับ c3p0 คือการแทนที่การรวมการเชื่อมต่อ DBCP มาตรฐานที่มาพร้อมกับ Apache Tomcat บ่อยครั้งที่โปรแกรมเมอร์จะทำงานในสถานการณ์ที่การเชื่อมต่อไม่ได้รีไซเคิลอย่างถูกต้องในกลุ่มการเชื่อมต่อ DBCP และ c3p0 เป็นสิ่งทดแทนที่มีค่าในกรณีนี้

ในการอัปเดตปัจจุบัน C3P0 มีคุณสมบัติที่ยอดเยี่ยมบางอย่าง เหล่านั้นจะได้รับร้อง:

ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setMinPoolSize();
dataSource.setMaxPoolSize();
dataSource.setMaxIdleTime();
dataSource.setMaxStatements();
dataSource.setMaxStatementsPerConnection();
dataSource.setMaxIdleTimeExcessConnections();

ที่นี่maxizeและ min poolizeจะกำหนดขอบเขตของการเชื่อมต่อซึ่งหมายความว่าแอปพลิเคชันนี้จะใช้การเชื่อมต่อขั้นต่ำและสูงสุดอย่างไร MaxIdleTime()กำหนดเมื่อมันจะปล่อยการเชื่อมต่อที่ไม่ได้ใช้งาน

DBCP :

วิธีนี้ยังดี แต่มีข้อบกพร่องบางอย่างเช่นการหมดเวลาการเชื่อมต่อและการเชื่อมต่อใหม่ C3P0 นั้นดีเมื่อเราใช้ mutithreading โปรเจค ในโครงการของเราเราใช้การประมวลผลหลายเธรดพร้อมกันโดยใช้ DBCP จากนั้นเราได้รับการหมดเวลาเชื่อมต่อหากเราใช้การประมวลผลเธรดมากขึ้น ดังนั้นเราจึงไปกับการกำหนดค่า c3p0 ฉันจะไม่แนะนำ DBCP เลยโดยเฉพาะอย่างยิ่งความสามารถในการโยนการเชื่อมต่อออกจากพูลเมื่อฐานข้อมูลหายไปความสามารถในการเชื่อมต่ออีกครั้งเมื่อฐานข้อมูลกลับมาและไม่สามารถเพิ่มวัตถุเชื่อมต่อกลับเข้าไปในกลุ่มได้ อ่านโพสต์ซ็อกเก็ต JDBCconnect I / O)

ขอบคุณ :)


1

คำแนะนำของฉันคือ

ฮิคาริ> druid> UCP> c3p0> DBCP

มันขึ้นอยู่กับสิ่งที่ฉันได้ทดสอบ - 20190202 ในสภาพแวดล้อมการทดสอบในพื้นที่ของฉัน (4GB mac / mysql ใน docker / pool minSize = 1, maxSize = 8), hikari สามารถให้บริการ 1024 เธรด x 1024 ครั้งเพื่อรับการเชื่อมต่อเวลาเฉลี่ยสำหรับแต่ละเธรด เพื่อเสร็จสิ้นคือ 1 หรือ 2 ล้านวินาทีในขณะที่ c3p0 สามารถให้บริการได้ 256 เธรด x 1024 ครั้งและเวลาเฉลี่ยสำหรับแต่ละเธรดนั้นมีอยู่แล้ว 21 ล้านวินาที (512 กระทู้ล้มเหลว)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.